Merge tag 'ntfs-for-7.1-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs

Pull ntfs updates from Namjae Jeon:

 - Fix potential data leakage by zeroing the portion of the straddle
   block beyond initialized_size when reading non-resident attributes

 - Remove unnecessary zeroing in ntfs_punch_hole() for ranges beyond
   initialized_size, as they are already returned as zeros on read

 - Fix writable check in ntfs_file_mmap_prepare() to correctly handle
   shared mappings using VMA_SHARED_BIT | VMA_MAYWRITE_BIT

 - Use page allocation instead of kmemdup() for IOMAP_INLINE data to
   ensure page-aligned address and avoid BUG trap in
   iomap_inline_data_valid() caused by the page boundary check

 - Add a size check before memory allocation in ntfs_attr_readall() and
   reject overly large attributes

 - Remove unneeded noop_direct_IO from ntfs_aops as it is no longer
   required following the FMODE_CAN_ODIRECT flag

 - Fix seven static analysis warnings reported by Smatch

* tag 'ntfs-for-7.1-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/ntfs:
  ntfs: use page allocation for resident attribute inline data
  ntfs: fix mmap_prepare writable check for shared mappings
  ntfs: fix potential 32-bit truncation in ntfs_write_cb()
  ntfs: fix uninitialized variable in ntfs_map_runlist_nolock
  ntfs: delete dead code
  ntfs: add missing error code in ntfs_mft_record_alloc()
  ntfs: fix uninitialized variables in ntfs_ea_set_wsl_inode()
  ntfs: fix uninitialized pointer in ntfs_write_mft_block
  ntfs: fix uninitialized variable in ntfs_write_simple_iomap_begin_non_resident
  ntfs: remove noop_direct_IO from address_space_operations
  ntfs: limit memory allocation in ntfs_attr_readall
  ntfs: not zero out range beyond init in punch_hole
  ntfs: zero out stale data in straddle block beyond initialized_size
diff --git a/.mailmap b/.mailmap
index 4cdb798..34acd34 100644
--- a/.mailmap
+++ b/.mailmap
@@ -338,6 +338,7 @@
 Huacai Chen <chenhuacai@kernel.org> <chenhc@lemote.com>
 Huacai Chen <chenhuacai@kernel.org> <chenhuacai@loongson.cn>
 Ignat Korchagin <ignat@linux.win> <ignat@cloudflare.com>
+Igor Korotin <igor.korotin@linux.dev> <igor.korotin.linux@gmail.com>
 Ike Panhc <ikepanhc@gmail.com> <ike.pan@canonical.com>
 J. Bruce Fields <bfields@fieldses.org> <bfields@redhat.com>
 J. Bruce Fields <bfields@fieldses.org> <bfields@citi.umich.edu>
@@ -586,6 +587,7 @@
 Michel Lespinasse <michel@lespinasse.org> <walken@zoy.org>
 Mickaël Salaün <mic@digikod.net> <mic@linux.microsoft.com>
 Miguel Ojeda <ojeda@kernel.org> <miguel.ojeda.sandonis@gmail.com>
+Mike Leach <mike.leach@arm.com> <mike.leach@linaro.org>
 Mike Rapoport <rppt@kernel.org> <mike@compulab.co.il>
 Mike Rapoport <rppt@kernel.org> <mike.rapoport@gmail.com>
 Mike Rapoport <rppt@kernel.org> <rppt@linux.ibm.com>
@@ -743,6 +745,7 @@
 Saravana Kannan <saravanak@kernel.org> <skannan@codeaurora.org>
 Saravana Kannan <saravanak@kernel.org> <saravanak@google.com>
 Sascha Hauer <s.hauer@pengutronix.de>
+Sasha Finkelstein <k@chaosmail.tech> <fnkl.kernel@gmail.com>
 Sahitya Tummala <quic_stummala@quicinc.com> <stummala@codeaurora.org>
 Sathishkumar Muruganandam <quic_murugana@quicinc.com> <murugana@codeaurora.org>
 Satya Priya <quic_skakitap@quicinc.com> <quic_c_skakit@quicinc.com> <skakit@codeaurora.org>
diff --git a/CREDITS b/CREDITS
index bee8609..17962bd 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1451,6 +1451,14 @@
 E: andy@greyhouse.net
 D: Maintenance and contributions to the network interface bonding driver.
 
+N: Vivek Goyal
+E: vgoyal@redhat.com
+D: KDUMP, KEXEC, and VIRTIO FILE SYSTEM
+
+N: Alexander Graf
+E: graf@amazon.com
+D: Kexec Handover (KHO)
+
 N: Wolfgang Grandegger
 E: wg@grandegger.com
 D: Controller Area Network (device drivers)
@@ -3644,6 +3652,11 @@
 S: S-226 64 LUND
 S: Sweden
 
+N: Tilman Schmidt
+E: tilman@imap.cc
+D: Siemens Gigaset ISDN driver author and maintainer
+D: ISDN CAPI subsystem contributions
+
 N: Henning P. Schmiedehausen
 E: hps@tanstaafl.de
 D: added PCI support to the serial driver
diff --git a/Documentation/.renames.txt b/Documentation/.renames.txt
index a37d684..43d4475 100644
--- a/Documentation/.renames.txt
+++ b/Documentation/.renames.txt
@@ -783,11 +783,9 @@
 namespaces/index admin-guide/namespaces/index
 namespaces/resource-control admin-guide/namespaces/resource-control
 networking/altera_tse networking/device_drivers/ethernet/altera/altera_tse
-networking/baycom networking/device_drivers/hamradio/baycom
 networking/bpf_flow_dissector bpf/prog_flow_dissector
 networking/cxacru networking/device_drivers/atm/cxacru
 networking/defza networking/device_drivers/fddi/defza
-networking/device_drivers/3com/3c509 networking/device_drivers/ethernet/3com/3c509
 networking/device_drivers/3com/vortex networking/device_drivers/ethernet/3com/vortex
 networking/device_drivers/amazon/ena networking/device_drivers/ethernet/amazon/ena
 networking/device_drivers/aquantia/atlantic networking/device_drivers/ethernet/aquantia/atlantic
@@ -822,7 +820,6 @@
 networking/device_drivers/netronome/nfp networking/device_drivers/ethernet/netronome/nfp
 networking/device_drivers/pensando/ionic networking/device_drivers/ethernet/pensando/ionic
 networking/device_drivers/qualcomm/rmnet networking/device_drivers/cellular/qualcomm/rmnet
-networking/device_drivers/smsc/smc9 networking/device_drivers/ethernet/smsc/smc9
 networking/device_drivers/stmicro/stmmac networking/device_drivers/ethernet/stmicro/stmmac
 networking/device_drivers/ti/cpsw networking/device_drivers/ethernet/ti/cpsw
 networking/device_drivers/ti/cpsw_switchdev networking/device_drivers/ethernet/ti/cpsw_switchdev
@@ -836,19 +833,16 @@
 networking/e1000 networking/device_drivers/ethernet/intel/e1000
 networking/e1000e networking/device_drivers/ethernet/intel/e1000e
 networking/fm10k networking/device_drivers/ethernet/intel/fm10k
-networking/fore200e networking/device_drivers/atm/fore200e
 networking/hinic networking/device_drivers/ethernet/huawei/hinic
 networking/i40e networking/device_drivers/ethernet/intel/i40e
 networking/iavf networking/device_drivers/ethernet/intel/iavf
 networking/ice networking/device_drivers/ethernet/intel/ice
 networking/igb networking/device_drivers/ethernet/intel/igb
 networking/igbvf networking/device_drivers/ethernet/intel/igbvf
-networking/iphase networking/device_drivers/atm/iphase
 networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
 networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
 networking/netdev-FAQ process/maintainer-netdev
 networking/skfp networking/device_drivers/fddi/skfp
-networking/z8530drv networking/device_drivers/hamradio/z8530drv
 nfc/index driver-api/nfc/index
 nfc/nfc-hci driver-api/nfc/nfc-hci
 nfc/nfc-pn544 driver-api/nfc/nfc-pn544
diff --git a/Documentation/ABI/stable/sysfs-driver-speakup b/Documentation/ABI/stable/sysfs-driver-speakup
index 8b508b4..69c26b9 100644
--- a/Documentation/ABI/stable/sysfs-driver-speakup
+++ b/Documentation/ABI/stable/sysfs-driver-speakup
@@ -16,8 +16,8 @@
 KernelVersion:	2.6
 Contact:	speakup@linux-speakup.org
 Description:	This controls whether one hears beeps through the PC speaker
-		when using speakup's review commands.
-		TODO: what values does it accept?
+		when using speakup's review commands. Range: 0-3. 0 = off, 1 = beeps
+		only, 2 = announcements only, 3 = beeps and announcements (default).
 
 What:		/sys/accessibility/speakup/bleep_time
 KernelVersion:	2.6
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index f8016df6..bc36ba3 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -278,3 +278,13 @@
 KernelVersion   6.18
 Contact:        Mao Jinlong <quic_jinlmao@quicinc.com>
 Description:    (Read) Show hardware context information of device.
+
+What:		/sys/bus/coresight/devices/<tpdm-name>/traceid
+Date:		March 2026
+KernelVersion:	7.1
+Contact:	Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+		(R) Show the trace ID that will appear in the trace stream
+		coming from this TPDM. The trace ID is inherited from the
+		connected TPDA device and is fixed for the lifetime of the
+		device. Returns -EINVAL if the device has not been enabled yet.
diff --git a/Documentation/ABI/testing/sysfs-bus-i3c b/Documentation/ABI/testing/sysfs-bus-i3c
index c1e0489..19f5cf8 100644
--- a/Documentation/ABI/testing/sysfs-bus-i3c
+++ b/Documentation/ABI/testing/sysfs-bus-i3c
@@ -172,3 +172,23 @@
 		the automatic retries. Exist only when I3C constroller supports
 		this retry on nack feature.
 
+What:		/sys/bus/i3c/devices/i3c-<bus-id>/do_daa
+KernelVersion:  7.0
+Contact:	linux-i3c@vger.kernel.org
+Description:
+		Write-only attribute that triggers a Dynamic Address Assignment
+		(DAA) procedure which discovers new I3C devices on the bus.
+		Writing a boolean true value (1, y, yes, true, on) to this
+		attribute causes the master controller to perform DAA, which
+		includes broadcasting an ENTDAA (Enter Dynamic Address Assignment)
+		Common Command Code (CCC) on the bus. Writing a false value
+		returns -EINVAL.
+
+		This is useful for discovering I3C devices that were not present
+		during initial bus initialization and are unable to issue
+		Hot-Join. Only devices without a currently assigned dynamic address
+		will respond to the ENTDAA broadcast and be assigned addresses.
+
+		Note that this mechanism is distinct from Hot-Join, since this is
+		controller-initiated discovery, while Hot-Join is device-initiated
+		method to provoke controller discovery procedure.
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 5f87dce..4fc9f6b 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -1428,7 +1428,7 @@
 Contact:	linux-iio@vger.kernel.org
 Description:
 		The name of the trigger source being used, as per string given
-		in /sys/class/iio/triggerY/name.
+		in /sys/bus/iio/devices/triggerY/name.
 
 What:		/sys/bus/iio/devices/iio:deviceX/bufferY/length
 KernelVersion:	5.11
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index 4b21d5d..32697b9 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -675,7 +675,8 @@
 
 		Valid values:
 			      "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD",
-			      "PD_DRP", "PD_PPS", "BrickID"
+			      "PD_DRP", "PD_PPS", "BrickID", "PD_SPR_AVS",
+			      "PD_PPS_SPR_AVS"
 
 **Device Specific Properties**
 
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs
index a90612a..3c422aa 100644
--- a/Documentation/ABI/testing/sysfs-driver-ufs
+++ b/Documentation/ABI/testing/sysfs-driver-ufs
@@ -1768,3 +1768,26 @@
 		====================   ===========================
 
 		The attribute is read only.
+
+What:		/sys/bus/platform/drivers/ufshcd/*/dme_qos_notification
+What:		/sys/bus/platform/devices/*.ufs/dme_qos_notification
+Date:		March 2026
+Contact:	Can Guo <can.guo@oss.qualcomm.com>
+Description:
+		This attribute reports and clears pending DME (Device Management
+		Entity) Quality of Service (QoS) notifications. This attribute
+		is a bitfield with the following bit assignments:
+
+		Bit	Description
+		===	======================================
+		0	DME QoS Monitor has been reset by host
+		1	QoS from TX is detected
+		2	QoS from RX is detected
+		3	QoS from PA_INIT is detected
+
+		Reading this attribute returns the pending DME QoS notification
+		bits. Writing '0' to this attribute clears pending DME QoS
+		notification bits. Writing any non-zero value is invalid and
+		will be rejected.
+
+		The attribute is read/write.
diff --git a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
index 2df7079..2397c65 100644
--- a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
+++ b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop
@@ -51,3 +51,30 @@
 
 		Reading this file returns the current status of the breathing animation
 		functionality.
+
+What:		/sys/bus/platform/devices/INOU0000:XX/ctgp_offset
+Date:		January 2026
+KernelVersion:	7.0
+Contact:	Werner Sembach <wse@tuxedocomputers.com>
+Description:
+		Allows userspace applications to set the configurable TGP offset on top of the base
+		TGP. Base TGP and max TGP and therefore the max cTGP offset are device specific.
+		Note that setting the maximum cTGP leaves no window open for Dynamic Boost as
+		Dynamic Boost also can not go over max TGP. Setting the cTGP to maximum is
+		effectively disabling Dynamic Boost and telling the device to always prioritize the
+		GPU over the CPU.
+
+		Reading this file returns the current configurable TGP offset.
+
+What:		/sys/bus/platform/devices/INOU0000:XX/usb_c_power_priority
+Date:		February 2026
+KernelVersion:	7.1
+Contact:	Werner Sembach <wse@tuxedocomputers.com>
+Description:
+		Allows userspace applications to choose the USB-C power distribution profile between
+		one that offers a bigger share of the power to the battery and one that offers more
+		of it to the CPU. Writing "charging"/"performance" into this file selects the
+		respective profile.
+
+		Reading this file returns the profile names with the currently active one in
+		brackets.
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index c1d2b3f..423ec40 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -407,6 +407,12 @@
 Description:	Average number of valid blocks.
 		Available when CONFIG_F2FS_STAT_FS=y.
 
+What:		/sys/fs/f2fs/<disk>/defrag_blocks
+Date:		February 2026
+Contact:	"Jinbao Liu" <liujinbao1@xiaomi.com>
+Description:	Number of blocks moved by defragment.
+		Available when CONFIG_F2FS_STAT_FS=y.
+
 What:		/sys/fs/f2fs/<disk>/mounted_time_sec
 Date:		February 2020
 Contact:	"Jaegeuk Kim" <jaegeuk@kernel.org>
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index cf38076..4d0f545 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6,7 +6,6 @@
 	APPARMOR AppArmor support is enabled.
 	ARM	ARM architecture is enabled.
 	ARM64	ARM64 architecture is enabled.
-	AX25	Appropriate AX.25 support is enabled.
 	CLK	Common clock infrastructure is enabled.
 	CMA	Contiguous Memory Area support is enabled.
 	DRM	Direct Rendering Management support is enabled.
@@ -633,23 +632,6 @@
 			1 - Enable the BAU.
 			unset - Disable the BAU.
 
-	baycom_epp=	[HW,AX25]
-			Format: <io>,<mode>
-
-	baycom_par=	[HW,AX25] BayCom Parallel Port AX.25 Modem
-			Format: <io>,<mode>
-			See header of drivers/net/hamradio/baycom_par.c.
-
-	baycom_ser_fdx=	[HW,AX25]
-			BayCom Serial Port AX.25 Modem (Full Duplex Mode)
-			Format: <io>,<irq>,<mode>[,<baud>]
-			See header of drivers/net/hamradio/baycom_ser_fdx.c.
-
-	baycom_ser_hdx=	[HW,AX25]
-			BayCom Serial Port AX.25 Modem (Half Duplex Mode)
-			Format: <io>,<irq>,<mode>
-			See header of drivers/net/hamradio/baycom_ser_hdx.c.
-
 	bdev_allow_write_mounted=
 			Format: <bool>
 			Control the ability to open a mounted block device
diff --git a/Documentation/admin-guide/laptops/thinkpad-acpi.rst b/Documentation/admin-guide/laptops/thinkpad-acpi.rst
index 03951ed..f874db3 100644
--- a/Documentation/admin-guide/laptops/thinkpad-acpi.rst
+++ b/Documentation/admin-guide/laptops/thinkpad-acpi.rst
@@ -1522,6 +1522,27 @@
 The property is read-only. If the platform doesn't have support the sysfs
 class is not created.
 
+doubletap_enable
+----------------
+
+sysfs: doubletap_enable
+
+Controls whether TrackPoint doubletap events are filtered out. Doubletap is a
+feature where quickly tapping the TrackPoint twice triggers a special function key event.
+
+The available commands are::
+
+                cat /sys/devices/platform/thinkpad_acpi/doubletap_enable
+                echo 1 | sudo tee /sys/devices/platform/thinkpad_acpi/doubletap_enable
+                echo 0 | sudo tee /sys/devices/platform/thinkpad_acpi/doubletap_enable
+
+Values:
+
+	* 1 - doubletap events are processed (default)
+	* 0 - doubletap events are filtered out (ignored)
+
+	This setting can also be toggled via the Fn+doubletap hotkey.
+
 Auxmac
 ------
 
diff --git a/Documentation/admin-guide/laptops/uniwill-laptop.rst b/Documentation/admin-guide/laptops/uniwill-laptop.rst
index aff5f57..5613348 100644
--- a/Documentation/admin-guide/laptops/uniwill-laptop.rst
+++ b/Documentation/admin-guide/laptops/uniwill-laptop.rst
@@ -50,6 +50,10 @@
 Additionally the driver signals the presence of battery charging issues through the standard
 ``health`` power supply sysfs attribute.
 
+It also lets you set whether a USB-C power source should prioritise charging the battery or
+delivering immediate power to the cpu. See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for
+details.
+
 Lightbar
 --------
 
@@ -58,3 +62,11 @@
 
 See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details on how to control the various
 animation modes of the lightbar.
+
+Configurable TGP
+----------------
+
+The ``uniwill-laptop`` driver allows to set the configurable TGP for devices with NVIDIA GPUs that
+allow it.
+
+See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details.
diff --git a/Documentation/admin-guide/mm/damon/lru_sort.rst b/Documentation/admin-guide/mm/damon/lru_sort.rst
index a7dea7c..14cc6b2 100644
--- a/Documentation/admin-guide/mm/damon/lru_sort.rst
+++ b/Documentation/admin-guide/mm/damon/lru_sort.rst
@@ -79,6 +79,10 @@
 parameter is set as ``N``.  If invalid parameters are found while the
 re-reading, DAMON_LRU_SORT will be disabled.
 
+Once ``Y`` is written to this parameter, the user must not write to any
+parameters until reading ``commit_inputs`` again returns ``N``.  If users
+violate this rule, the kernel may exhibit undefined behavior.
+
 active_mem_bp
 -------------
 
diff --git a/Documentation/admin-guide/mm/damon/reclaim.rst b/Documentation/admin-guide/mm/damon/reclaim.rst
index 47854c4..d7a0225 100644
--- a/Documentation/admin-guide/mm/damon/reclaim.rst
+++ b/Documentation/admin-guide/mm/damon/reclaim.rst
@@ -71,6 +71,10 @@
 parameter is set as ``N``.  If invalid parameters are found while the
 re-reading, DAMON_RECLAIM will be disabled.
 
+Once ``Y`` is written to this parameter, the user must not write to any
+parameters until reading ``commit_inputs`` again returns ``N``.  If users
+violate this rule, the kernel may exhibit undefined behavior.
+
 min_age
 -------
 
diff --git a/Documentation/admin-guide/mm/kho.rst b/Documentation/admin-guide/mm/kho.rst
index cb9a20f..2c26e56 100644
--- a/Documentation/admin-guide/mm/kho.rst
+++ b/Documentation/admin-guide/mm/kho.rst
@@ -42,6 +42,45 @@
 an early memory reservation, the new kernel will have that memory at the
 same physical address as the old kernel.
 
+Kexec Metadata
+==============
+
+KHO automatically tracks metadata about the kexec chain, passing information
+about the previous kernel to the next kernel. This feature helps diagnose
+bugs that only reproduce when kexecing from specific kernel versions.
+
+On each KHO kexec, the kernel logs the previous kernel's version and the
+number of kexec reboots since the last cold boot::
+
+    [    0.000000] KHO: exec from: 6.19.0-rc4-next-20260107 (count 1)
+
+The metadata includes:
+
+``previous_release``
+    The kernel version string (from ``uname -r``) of the kernel that
+    initiated the kexec.
+
+``kexec_count``
+    The number of kexec boots since the last cold boot. On cold boot,
+    this counter starts at 0 and increments with each kexec. This helps
+    identify issues that only manifest after multiple consecutive kexec
+    reboots.
+
+Use Cases
+---------
+
+This metadata is particularly useful for debugging kexec transition bugs,
+where a buggy kernel kexecs into a new kernel and the bug manifests only
+in the second kernel. Examples of such bugs include:
+
+- Memory corruption from the previous kernel affecting the new kernel
+- Incorrect hardware state left by the previous kernel
+- Firmware/ACPI state issues that only appear in kexec scenarios
+
+At scale, correlating crashes to the previous kernel version enables
+faster root cause analysis when issues only occur in specific kernel
+transition scenarios.
+
 debugfs Interfaces
 ==================
 
@@ -80,5 +119,5 @@
     it finished to interpret their metadata.
 
 ``/sys/kernel/debug/kho/in/sub_fdts/``
-    Similar to ``kho/out/sub_fdts/``, but contains sub FDT blobs
+    Similar to ``kho/out/sub_fdts/``, but contains sub blobs
     of KHO producers passed from the old kernel.
diff --git a/Documentation/admin-guide/nfs/pnfs-block-server.rst b/Documentation/admin-guide/nfs/pnfs-block-server.rst
index 20fe9f5..7667dd2 100644
--- a/Documentation/admin-guide/nfs/pnfs-block-server.rst
+++ b/Documentation/admin-guide/nfs/pnfs-block-server.rst
@@ -40,3 +40,33 @@
 
 	echo "fencing client ${CLIENT} serial ${EVPD}" >> /var/log/pnfsd-fence.log
 	EOF
+
+If the nfsd server needs to fence a non-responding client and the
+fencing operation fails, the server logs a warning message in the
+system log with the following format:
+
+    FENCE failed client[IP_address] clid[#n] device[dev_name]
+
+    where:
+
+    - IP_address: refers to the IP address of the affected client.
+    - #n: indicates the unique client identifier.
+    - dev_name: specifies the name of the block device related
+      to the fencing attempt.
+
+The server will repeatedly retry the operation indefinitely. During
+this time, access to the affected file is restricted for all other
+clients. This is to prevent potential data corruption if multiple
+clients access the same file simultaneously.
+
+To restore access to the affected file for other clients, the admin
+needs to take the following actions:
+
+    - shutdown or power off the client being fenced.
+    - manually expire the client to release all its state on the server::
+
+        echo 'expire' > /proc/fs/nfsd/clients/clid/ctl
+
+    where:
+
+      - clid: is the unique client identifier displayed in the system log.
diff --git a/Documentation/admin-guide/nfs/pnfs-scsi-server.rst b/Documentation/admin-guide/nfs/pnfs-scsi-server.rst
index b2eec22..b202508 100644
--- a/Documentation/admin-guide/nfs/pnfs-scsi-server.rst
+++ b/Documentation/admin-guide/nfs/pnfs-scsi-server.rst
@@ -22,3 +22,34 @@
 On the client make sure the kernel has the CONFIG_PNFS_BLOCK option
 enabled, and the file system is mounted using the NFSv4.1 protocol
 version (mount -o vers=4.1).
+
+If the nfsd server needs to fence a non-responding client and the
+fencing operation fails, the server logs a warning message in the
+system log with the following format:
+
+    FENCE failed client[IP_address] clid[#n] device[dev_name]
+
+    where:
+
+    - IP_address: refers to the IP address of the affected client.
+    - #n: indicates the unique client identifier.
+    - dev_name: specifies the name of the block device related
+      to the fencing attempt.
+
+The server will repeatedly retry the operation indefinitely. During
+this time, access to the affected file is restricted for all other
+clients. This is to prevent potential data corruption if multiple
+clients access the same file simultaneously.
+
+To restore access to the affected file for other clients, the admin
+needs to take the following actions:
+
+    - shutdown or power off the client being fenced.
+    - manually expire the client to release all its state on the server::
+
+        echo 'expire' > /proc/fs/nfsd/clients/clid/ctl
+
+    where:
+
+      - clid: is the unique client identifier displayed in the system log.
+
diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/arch/arm64/silicon-errata.rst
index 4e0e889..211119c 100644
--- a/Documentation/arch/arm64/silicon-errata.rst
+++ b/Documentation/arch/arm64/silicon-errata.rst
@@ -202,6 +202,8 @@
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Neoverse-V3AE   | #3312417        | ARM64_ERRATUM_3194386       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | C1-Pro          | #4193714        | ARM64_ERRATUM_4193714       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | MMU-500         | #841119,826419  | ARM_SMMU_MMU_500_CPRE_ERRATA|
 |                |                 | #562869,1047329 |                             |
 +----------------+-----------------+-----------------+-----------------------------+
diff --git a/Documentation/arch/s390/pci.rst b/Documentation/arch/s390/pci.rst
index d575548..80f4ba1 100644
--- a/Documentation/arch/s390/pci.rst
+++ b/Documentation/arch/s390/pci.rst
@@ -6,6 +6,7 @@
 
 Authors:
         - Pierre Morel
+        - Niklas Schnelle
 
 Copyright, IBM Corp. 2020
 
@@ -27,14 +28,16 @@
 debugfs entries
 ---------------
 
-The S/390 debug feature (s390dbf) generates views to hold various debug results in sysfs directories of the form:
+The S/390 debug feature (s390dbf) generates views to hold various debug results
+in sysfs directories of the form:
 
  * /sys/kernel/debug/s390dbf/pci_*/
 
 For example:
 
   - /sys/kernel/debug/s390dbf/pci_msg/sprintf
-    Holds messages from the processing of PCI events, like machine check handling
+
+    holds messages from the processing of PCI events, like machine check handling
     and setting of global functionality, like UID checking.
 
   Change the level of logging to be more or less verbose by piping
@@ -47,87 +50,141 @@
 
 Entries specific to zPCI functions and entries that hold zPCI information.
 
-* /sys/bus/pci/slots/XXXXXXXX
+* /sys/bus/pci/slots/XXXXXXXX:
 
-  The slot entries are set up using the function identifier (FID) of the
-  PCI function. The format depicted as XXXXXXXX above is 8 hexadecimal digits
-  with 0 padding and lower case hexadecimal digits.
+  The slot entries are set up using the function identifier (FID) of the PCI
+  function as slot name. The format depicted as XXXXXXXX above is 8 hexadecimal
+  digits with 0 padding and lower case hexadecimal digits.
 
   - /sys/bus/pci/slots/XXXXXXXX/power
 
+  In addition to using the FID as the name of the slot, the slot directory
+  also contains the following s390-specific slot attributes.
+
+  - uid:
+    The User-defined identifier (UID) of the function which may be configured
+    by this slot. See also the corresponding attribute of the device.
+
   A physical function that currently supports a virtual function cannot be
   powered off until all virtual functions are removed with:
-  echo 0 > /sys/bus/pci/devices/XXXX:XX:XX.X/sriov_numvf
+  echo 0 > /sys/bus/pci/devices/DDDD:BB:dd.f/sriov_numvf
 
-* /sys/bus/pci/devices/XXXX:XX:XX.X/
+* /sys/bus/pci/devices/DDDD:BB:dd.f/:
 
-  - function_id
-    A zPCI function identifier that uniquely identifies the function in the Z server.
+  - function_id:
+    The zPCI function identifier (FID) is a 32-bit hexadecimal value that
+    uniquely identifies the PCI function. Unless the hypervisor provides
+    a virtual FID e.g. on KVM this identifier is unique across the machine even
+    between different partitions.
 
-  - function_handle
-    Low-level identifier used for a configured PCI function.
-    It might be useful for debugging.
+  - function_handle:
+    This 32-bit hexadecimal value is a low-level identifier used for a PCI
+    function. Note that the function handle may be changed and become invalid
+    on PCI events and when enabling/disabling the PCI function.
 
-  - pchid
-    Model-dependent location of the I/O adapter.
+  - pchid:
+    This 16-bit hexadecimal value encodes a model-dependent location for
+    the PCI function.
 
-  - pfgid
-    PCI function group ID, functions that share identical functionality
+  - pfgid:
+    PCI function group ID; functions that share identical functionality
     use a common identifier.
     A PCI group defines interrupts, IOMMU, IOTLB, and DMA specifics.
 
-  - vfn
+  - vfn:
     The virtual function number, from 1 to N for virtual functions,
     0 for physical functions.
 
-  - pft
-    The PCI function type
+  - pft:
+    The PCI function type is an s390-specific type attribute. It indicates
+    a more general, usage oriented, type than PCI Specification
+    class/vendor/device identifiers. That is PCI functions with the same pft
+    value may be backed by different hardware implementations. At the same time
+    apart from unclassified functions (pft is 0x00) the same pft value
+    generally implies a similar usage model. At the same time the same
+    PCI hardware device may appear with different pft values when in a
+    different usage model. For example NETD and NETH VFs may be implemented
+    by the same PCI hardware device but in NETD the parent Physical Function
+    is user managed while with NETH it is platform managed.
 
-  - port
-    The port corresponds to the physical port the function is attached to.
-    It also gives an indication of the physical function a virtual function
-    is attached to.
+    Currently the following PFT values are defined:
 
-  - uid
-    The user identifier (UID) may be defined as part of the machine
-    configuration or the z/VM or KVM guest configuration. If the accompanying
-    uid_is_unique attribute is 1 the platform guarantees that the UID is unique
-    within that instance and no devices with the same UID can be attached
-    during the lifetime of the system.
+    - 0x00 (UNC): Unclassified
+    - 0x02 (ROCE): RoCE Express
+    - 0x05 (ISM): Internal Shared Memory
+    - 0x0a (ROC2): RoCE Express 2
+    - 0x0b (NVMe): NVMe
+    - 0x0c (NETH): Network Express hybrid
+    - 0x0d (CNW): Cloud Network Adapter
+    - 0x0f (NETD): Network Express direct
 
-  - uid_is_unique
-    Indicates whether the user identifier (UID) is guaranteed to be and remain
-    unique within this Linux instance.
+  - port:
+    The port is a decimal value corresponding to the physical port the function
+    is attached to. Virtual Functions (VFs) share the port with their parent
+    Physical Function (PF). A value of 0 indicates that the port attribute is
+    not applicable for that PCI function type.
 
-  - pfip/segmentX
+  - uid:
+    The user-defined identifier (UID) for a PCI function is a 32-bit
+    hexadecimal value. It is defined on a per instance basis as part of the
+    partition, KVM guest, or z/VM guest configuration. If UID Checking is
+    enabled the platform ensures that the UID is unique within that instance
+    and no two PCI functions with the same UID will be visible to the instance.
+
+    Independent of this guarantee and unlike the function ID (FID) the UID may
+    be the same in different partitions within the same machine. This allows to
+    create PCI configurations in multiple partitions to be identical in the
+    UID-namespace.
+
+  - uid_is_unique:
+    A 0 or 1 flag indicating whether the user-defined identifier (UID) is
+    guaranteed to be and remain unique within this Linux instance. This
+    platform feature is called UID Checking.
+
+  - pfip/segmentX:
     The segments determine the isolation of a function.
     They correspond to the physical path to the function.
     The more the segments are different, the more the functions are isolated.
 
+  - fidparm:
+    Contains an 8-bit-per-PCI function parameter field in hexadecimal provided
+    by the platform. The meaning of this field is PCI function type specific.
+    For NETH VFs a value of 0x01 indicates that the function supports
+    promiscuous mode.
+
+* /sys/firmware/clp/uid_checking:
+
+  In addition to the per-device uid_is_unique attribute this presents a
+  global indication of whether UID Checking is enabled. This allows users
+  to check for UID Checking even when no PCI functions are configured.
+
 Enumeration and hotplug
 =======================
 
 The PCI address consists of four parts: domain, bus, device and function,
-and is of this form: DDDD:BB:dd.f
+and is of this form: DDDD:BB:dd.f.
 
-* When not using multi-functions (norid is set, or the firmware does not
-  support multi-functions):
+* For a PCI function for which the platform does not expose the RID, the
+  pci=norid kernel parameter is used, or a so-called isolated Virtual Function
+  which does have RID information but is used without its parent Physical
+  Function being part of the same PCI configuration:
 
   - There is only one function per domain.
 
-  - The domain is set from the zPCI function's UID as defined during the
-    LPAR creation.
+  - The domain is set from the zPCI function's UID if UID Checking is on;
+    otherwise the domain ID is generated dynamically and is not stable
+    across reboots or hot plug.
 
-* When using multi-functions (norid parameter is not set),
-  zPCI functions are addressed differently:
+* For a PCI function for which the platform exposes the RID and which
+  is not an Isolated Virtual Function:
 
   - There is still only one bus per domain.
 
-  - There can be up to 256 functions per bus.
+  - There can be up to 256 PCI functions per bus.
 
-  - The domain part of the address of all functions for
-    a multi-Function device is set from the zPCI function's UID as defined
-    in the LPAR creation for the function zero.
+  - The domain part of the address of all functions within the same topology is
+    that of the configured PCI function with the lowest devfn within that
+    topology.
 
-  - New functions will only be ready for use after the function zero
-    (the function with devfn 0) has been enumerated.
+  - Virtual Functions generated by an SR-IOV capable Physical Function only
+    become visible once SR-IOV is enabled.
diff --git a/Documentation/crypto/index.rst b/Documentation/crypto/index.rst
index 4ee667c..705f186 100644
--- a/Documentation/crypto/index.rst
+++ b/Documentation/crypto/index.rst
@@ -13,6 +13,7 @@
    :caption: Table of contents
    :maxdepth: 2
 
+   libcrypto
    intro
    api-intro
    architecture
@@ -27,4 +28,3 @@
    descore-readme
    device_drivers/index
    krb5
-   sha3
diff --git a/Documentation/crypto/libcrypto-blockcipher.rst b/Documentation/crypto/libcrypto-blockcipher.rst
new file mode 100644
index 0000000..dd5ce2f
--- /dev/null
+++ b/Documentation/crypto/libcrypto-blockcipher.rst
@@ -0,0 +1,19 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Block ciphers
+=============
+
+AES
+---
+
+Support for the AES block cipher.
+
+.. kernel-doc:: include/crypto/aes.h
+
+DES
+---
+
+Support for the DES block cipher.  This algorithm is obsolete and is supported
+only for backwards compatibility.
+
+.. kernel-doc:: include/crypto/des.h
diff --git a/Documentation/crypto/libcrypto-hash.rst b/Documentation/crypto/libcrypto-hash.rst
new file mode 100644
index 0000000..4248e6f
--- /dev/null
+++ b/Documentation/crypto/libcrypto-hash.rst
@@ -0,0 +1,86 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Hash functions, MACs, and XOFs
+==============================
+
+AES-CMAC and AES-XCBC-MAC
+-------------------------
+
+Support for the AES-CMAC and AES-XCBC-MAC message authentication codes.
+
+.. kernel-doc:: include/crypto/aes-cbc-macs.h
+
+BLAKE2b
+-------
+
+Support for the BLAKE2b cryptographic hash function.
+
+.. kernel-doc:: include/crypto/blake2b.h
+
+BLAKE2s
+-------
+
+Support for the BLAKE2s cryptographic hash function.
+
+.. kernel-doc:: include/crypto/blake2s.h
+
+GHASH and POLYVAL
+-----------------
+
+Support for the GHASH and POLYVAL universal hash functions.  These algorithms
+are used only as internal components of other algorithms.
+
+.. kernel-doc:: include/crypto/gf128hash.h
+
+MD5
+---
+
+Support for the MD5 cryptographic hash function and HMAC-MD5.  This algorithm is
+obsolete and is supported only for backwards compatibility.
+
+.. kernel-doc:: include/crypto/md5.h
+
+NH
+--
+
+Support for the NH universal hash function.  This algorithm is used only as an
+internal component of other algorithms.
+
+.. kernel-doc:: include/crypto/nh.h
+
+Poly1305
+--------
+
+Support for the Poly1305 universal hash function.  This algorithm is used only
+as an internal component of other algorithms.
+
+.. kernel-doc:: include/crypto/poly1305.h
+
+SHA-1
+-----
+
+Support for the SHA-1 cryptographic hash function and HMAC-SHA1.  This algorithm
+is obsolete and is supported only for backwards compatibility.
+
+.. kernel-doc:: include/crypto/sha1.h
+
+SHA-2
+-----
+
+Support for the SHA-2 family of cryptographic hash functions, including SHA-224,
+SHA-256, SHA-384, and SHA-512.  This also includes their corresponding HMACs:
+HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, and HMAC-SHA512.
+
+.. kernel-doc:: include/crypto/sha2.h
+
+SHA-3
+-----
+
+The SHA-3 functions are documented in :ref:`sha3`.
+
+SM3
+---
+
+Support for the SM3 cryptographic hash function.
+
+.. kernel-doc:: include/crypto/sm3.h
diff --git a/Documentation/crypto/libcrypto-signature.rst b/Documentation/crypto/libcrypto-signature.rst
new file mode 100644
index 0000000..e80d59fa
--- /dev/null
+++ b/Documentation/crypto/libcrypto-signature.rst
@@ -0,0 +1,11 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Digital signature algorithms
+============================
+
+ML-DSA
+------
+
+Support for the ML-DSA digital signature algorithm.
+
+.. kernel-doc:: include/crypto/mldsa.h
diff --git a/Documentation/crypto/libcrypto-utils.rst b/Documentation/crypto/libcrypto-utils.rst
new file mode 100644
index 0000000..9d833f4
--- /dev/null
+++ b/Documentation/crypto/libcrypto-utils.rst
@@ -0,0 +1,6 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+Utility functions
+=================
+
+.. kernel-doc:: include/crypto/utils.h
diff --git a/Documentation/crypto/libcrypto.rst b/Documentation/crypto/libcrypto.rst
new file mode 100644
index 0000000..a1557d4
--- /dev/null
+++ b/Documentation/crypto/libcrypto.rst
@@ -0,0 +1,165 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+==============
+Crypto library
+==============
+
+``lib/crypto/`` provides faster and easier access to cryptographic algorithms
+than the traditional crypto API.
+
+Each cryptographic algorithm is supported via a set of dedicated functions.
+"Crypto agility", where needed, is left to calling code.
+
+The crypto library functions are intended to be boring and straightforward, and
+to follow familiar conventions.  Their primary documentation is their (fairly
+extensive) kernel-doc.  This page just provides some extra high-level context.
+
+Note that the crypto library isn't entirely new.  ``lib/`` has contained some
+crypto functions since 2005.  Rather, it's just an approach that's been expanded
+over time as it's been found to work well.  It also largely just matches how the
+kernel already does things elsewhere.
+
+Scope and intended audience
+===========================
+
+The crypto library documentation is primarily meant for kernel developers who
+need to use a particular cryptographic algorithm(s) in kernel code.  For
+example, "I just need to compute a SHA-256 hash."  A secondary audience is
+developers working on the crypto algorithm implementations themselves.
+
+If you're looking for more general information about cryptography, like the
+differences between the different crypto algorithms or how to select an
+appropriate algorithm, you should refer to external sources which cover that
+type of information much more comprehensively.  If you need help selecting
+algorithms for a new kernel feature that doesn't already have its algorithms
+predefined, please reach out to ``linux-crypto@vger.kernel.org`` for advice.
+
+Code organization
+=================
+
+- ``lib/crypto/*.c``: the crypto algorithm implementations
+
+- ``lib/crypto/$(SRCARCH)/``: architecture-specific code for crypto algorithms.
+  It is here rather than somewhere in ``arch/`` partly because this allows
+  generic and architecture-optimized code to be easily built into a single
+  loadable module (when the algorithm is set to 'm' in the kconfig).
+
+- ``lib/crypto/tests/``: KUnit tests for the crypto algorithms
+
+- ``include/crypto/``: crypto headers, for both the crypto library and the
+  traditional crypto API
+
+Generally, there is one kernel module per algorithm.  Sometimes related
+algorithms are grouped into one module.  There is intentionally no common
+framework, though there are some utility functions that multiple algorithms use.
+
+Each algorithm module is controlled by a tristate kconfig symbol
+``CRYPTO_LIB_$(ALGORITHM)``.  As is the norm for library functions in the
+kernel, these are hidden symbols which don't show up in the kconfig menu.
+Instead, they are just selected by all the kconfig symbols that need them.
+
+Many of the algorithms have multiple implementations: a generic implementation
+and architecture-optimized implementation(s).  Each module initialization
+function, or initcall in the built-in case, automatically enables the best
+implementation based on the available CPU features.
+
+Note that the crypto library doesn't use the ``crypto/``,
+``arch/$(SRCARCH)/crypto/``, or ``drivers/crypto/`` directories.  These
+directories are used by the traditional crypto API.  When possible, algorithms
+in the traditional crypto API are implemented by calls into the library.
+
+Advantages
+==========
+
+Some of the advantages of the library over the traditional crypto API are:
+
+- The library functions tend to be much easier to use.  For example, a hash
+  value can be computed using only a single function call.  Most of the library
+  functions always succeed and return void, eliminating the need to write
+  error-handling code.  Most also accept standard virtual addresses, rather than
+  scatterlists which are difficult and less efficient to work with.
+
+- The library functions are usually faster, especially for short inputs.  They
+  call the crypto algorithms directly without inefficient indirect calls, memory
+  allocations, string parsing, lookups in an algorithm registry, and other
+  unnecessary API overhead.  Architecture-optimized code is enabled by default.
+
+- The library functions use standard link-time dependencies instead of
+  error-prone dynamic loading by name.  There's no need for workarounds such as
+  forcing algorithms to be built-in or adding module soft dependencies.
+
+- The library focuses on the approach that works the best on the vast majority
+  of systems: CPU-based implementations of the crypto algorithms, utilizing
+  on-CPU acceleration (such as AES instructions) when available.
+
+- The library uses standard KUnit tests, rather than custom ad-hoc tests.
+
+- The library tends to have higher assurance implementations of the crypto
+  algorithms.  This is both due to its simpler design and because more of its
+  code is being regularly tested.
+
+- The library supports features that don't fit into the rigid framework of the
+  traditional crypto API, for example interleaved hashing and XOFs.
+
+When to use it
+==============
+
+In-kernel users should use the library (rather than the traditional crypto API)
+whenever possible.  Many subsystems have already been converted.  It usually
+simplifies their code significantly and improves performance.
+
+Some kernel features allow userspace to provide an arbitrary string that selects
+an arbitrary algorithm from the traditional crypto API by name.  These features
+generally will have to keep using the traditional crypto API for backwards
+compatibility.
+
+Note: new kernel features shouldn't support every algorithm, but rather make a
+deliberate choice about what algorithm(s) to support.  History has shown that
+making a deliberate, thoughtful choice greatly simplifies code maintenance,
+reduces the chance for mistakes (such as using an obsolete, insecure, or
+inappropriate algorithm), and makes your feature easier to use.
+
+Testing
+=======
+
+The crypto library uses standard KUnit tests.  Like many of the kernel's other
+KUnit tests, they are included in the set of tests that is run by
+``tools/testing/kunit/kunit.py run --alltests``.
+
+A ``.kunitconfig`` file is also provided to run just the crypto library tests.
+For example, here's how to run them in user-mode Linux:
+
+.. code-block:: sh
+
+    tools/testing/kunit/kunit.py run --kunitconfig=lib/crypto/
+
+Many of the crypto algorithms have architecture-optimized implementations.
+Testing those requires building an appropriate kernel and running the tests
+either in QEMU or on appropriate hardware.  Here's one example with QEMU:
+
+.. code-block:: sh
+
+    tools/testing/kunit/kunit.py run --kunitconfig=lib/crypto/ --arch=arm64 --make_options LLVM=1
+
+Depending on the code being tested, flags may need to be passed to QEMU to
+emulate the correct type of hardware for the code to be reached.
+
+Since correctness is essential in cryptographic code, new architecture-optimized
+code is accepted only if it can be tested in QEMU.
+
+Note: the crypto library also includes FIPS 140 self-tests.  These are
+lightweight, are designed specifically to meet FIPS 140 requirements, and exist
+*only* to meet those requirements.  Normal testing done by kernel developers and
+integrators should use the much more comprehensive KUnit tests instead.
+
+API documentation
+=================
+
+.. toctree::
+   :maxdepth: 2
+
+   libcrypto-blockcipher
+   libcrypto-hash
+   libcrypto-signature
+   libcrypto-utils
+   sha3
diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst
index 37640f2..250669c 100644
--- a/Documentation/crypto/sha3.rst
+++ b/Documentation/crypto/sha3.rst
@@ -1,5 +1,7 @@
 .. SPDX-License-Identifier: GPL-2.0-or-later
 
+.. _sha3:
+
 ==========================
 SHA-3 Algorithm Collection
 ==========================
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml
index 4bc7454..7e77310 100644
--- a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml
+++ b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml
@@ -21,6 +21,17 @@
           - const: marvell,armada-ap806-dual
           - const: marvell,armada-ap806
 
+      - description:
+          Falcon (DB-98CX85x0) Development board COM Express Carrier plus
+          Armada 7020 SoC COM Express CPU module
+        items:
+          - const: marvell,armada7020-falcon-carrier
+          - const: marvell,db-falcon-carrier
+          - const: marvell,armada7020-cpu-module
+          - const: marvell,armada7020
+          - const: marvell,armada-ap806-dual
+          - const: marvell,armada-ap806
+
       - description: Armada 7040 SoC
         items:
           - enum:
diff --git a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
index fe1272e..1d2e242 100644
--- a/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
+++ b/Documentation/devicetree/bindings/auxdisplay/holtek,ht16k33.yaml
@@ -10,6 +10,7 @@
   - Robin van der Gracht <robin@protonic.nl>
 
 allOf:
+  - $ref: /schemas/input/input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 properties:
@@ -33,9 +34,7 @@
   interrupts:
     maxItems: 1
 
-  debounce-delay-ms:
-    maxItems: 1
-    description: Debouncing interval time in milliseconds
+  debounce-delay-ms: true
 
   linux,keymap: true
 
diff --git a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
index 9f9816f..fd1a459 100644
--- a/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
+++ b/Documentation/devicetree/bindings/chrome/google,cros-ec-typec.yaml
@@ -8,17 +8,28 @@
 
 maintainers:
   - Benson Leung <bleung@chromium.org>
-  - Prashant Malani <pmalani@chromium.org>
+  - Abhishek Pandit-Subedi <abhishekpandit@chromium.org>
+  - Andrei Kuchynski <akuchynski@chromium.org>
+  - Łukasz Bartosik <ukaszb@chromium.org>
+  - Jameson Thies <jthies@google.com>
 
 description:
   Chrome OS devices have an Embedded Controller(EC) which has access to
   Type C port state. This node is intended to allow the host to read and
-  control the Type C ports. The node for this device should be under a
-  cros-ec node like google,cros-ec-spi.
+  control the Type C ports. This binding is compatible with both the
+  cros-ec-typec and cros-ec-ucsi drivers. The cros-ec-typec driver
+  supports the host command interface used by the Chrome OS EC with a
+  built-in Type-C port manager and external Type-C Port Controller
+  (TCPC). The cros-ec-ucsi driver supports the USB Type-C Connector
+  System Software (UCSI) interface used by the Chrome OS EC when the
+  platform has a separate power delivery controller (PDC). The node for
+  this device should be under a cros-ec node like google,cros-ec-spi.
 
 properties:
   compatible:
-    const: google,cros-ec-typec
+    enum:
+      - google,cros-ec-typec
+      - google,cros-ec-ucsi
 
   '#address-cells':
     const: 1
diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
index a847136..eb24a56 100644
--- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
+++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml
@@ -32,6 +32,7 @@
       - enum:
           - airoha,en7523-scu
           - airoha,en7581-scu
+          - econet,en751221-scu
 
   reg:
     items:
@@ -67,7 +68,9 @@
   - if:
       properties:
         compatible:
-          const: airoha,en7581-scu
+          enum:
+            - airoha,en7581-scu
+            - econet,en751221-scu
     then:
       properties:
         reg:
@@ -98,3 +101,4 @@
               #reset-cells = <1>;
       };
     };
+
diff --git a/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml b/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml
deleted file mode 100644
index 30252c95..0000000
--- a/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-div.yaml
+++ /dev/null
@@ -1,196 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-div.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Baikal-T1 Clock Control Unit Dividers
-
-maintainers:
-  - Serge Semin <fancer.lancer@gmail.com>
-
-description: |
-  Clocks Control Unit is the core of Baikal-T1 SoC System Controller
-  responsible for the chip subsystems clocking and resetting. The CCU is
-  connected with an external fixed rate oscillator, which signal is transformed
-  into clocks of various frequencies and then propagated to either individual
-  IP-blocks or to groups of blocks (clock domains). The transformation is done
-  by means of an embedded into CCU PLLs and gateable/non-gateable dividers. The
-  later ones are described in this binding. Each clock domain can be also
-  individually reset by using the domain clocks divider configuration
-  registers. Baikal-T1 CCU is logically divided into the next components:
-  1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but
-     in general can provide any frequency supported by the CCU PLLs).
-  2) PLLs clocks generators (PLLs).
-  3) AXI-bus clock dividers (AXI) - described in this binding file.
-  4) System devices reference clock dividers (SYS) - described in this binding
-     file.
-  which are connected with each other as shown on the next figure:
-
-          +---------------+
-          | Baikal-T1 CCU |
-          |   +----+------|- MIPS P5600 cores
-          | +-|PLLs|------|- DDR controller
-          | | +----+      |
-  +----+  | |  |  |       |
-  |XTAL|--|-+  |  | +---+-|
-  +----+  | |  |  +-|AXI|-|- AXI-bus
-          | |  |    +---+-|
-          | |  |          |
-          | |  +----+---+-|- APB-bus
-          | +-------|SYS|-|- Low-speed Devices
-          |         +---+-|- High-speed Devices
-          +---------------+
-
-  Each sub-block is represented as a separate DT node and has an individual
-  driver to be bound with.
-
-  In order to create signals of wide range frequencies the external oscillator
-  output is primarily connected to a set of CCU PLLs. Some of PLLs CLKOUT are
-  then passed over CCU dividers to create signals required for the target clock
-  domain (like AXI-bus or System Device consumers). The dividers have the
-  following structure:
-
-          +--------------+
-  CLKIN --|->+----+ 1|\  |
-  SETCLK--|--|/DIV|->| | |
-  CLKDIV--|--|    |  | |-|->CLKLOUT
-  LOCK----|--+----+  | | |
-          |          |/  |
-          |           |  |
-  EN------|-----------+  |
-  RST-----|--------------|->RSTOUT
-          +--------------+
-
-  where CLKIN is the reference clock coming either from CCU PLLs or from an
-  external clock oscillator, SETCLK - a command to update the output clock in
-  accordance with a set divider, CLKDIV - clocks divider, LOCK - a signal of
-  the output clock stabilization, EN - enable/disable the divider block,
-  RST/RSTOUT - reset clocks domain signal. Depending on the consumer IP-core
-  peculiarities the dividers may lack of some functionality depicted on the
-  figure above (like EN, CLKDIV/LOCK/SETCLK). In this case the corresponding
-  clock provider just doesn't expose either switching functions, or the rate
-  configuration, or both of them.
-
-  The clock dividers, which output clock is then consumed by the SoC individual
-  devices, are united into a single clocks provider called System Devices CCU.
-  Similarly the dividers with output clocks utilized as AXI-bus reference clocks
-  are called AXI-bus CCU. Both of them use the common clock bindings with no
-  custom properties. The list of exported clocks and reset signals can be found
-  in the files: 'include/dt-bindings/clock/bt1-ccu.h' and
-  'include/dt-bindings/reset/bt1-ccu.h'. Since System Devices and AXI-bus CCU
-  are a part of the Baikal-T1 SoC System Controller their DT nodes are supposed
-  to be a children of later one.
-
-if:
-  properties:
-    compatible:
-      contains:
-        const: baikal,bt1-ccu-axi
-
-then:
-  properties:
-    clocks:
-      items:
-        - description: CCU SATA PLL output clock
-        - description: CCU PCIe PLL output clock
-        - description: CCU Ethernet PLL output clock
-
-    clock-names:
-      items:
-        - const: sata_clk
-        - const: pcie_clk
-        - const: eth_clk
-
-else:
-  properties:
-    clocks:
-      items:
-        - description: External reference clock
-        - description: CCU SATA PLL output clock
-        - description: CCU PCIe PLL output clock
-        - description: CCU Ethernet PLL output clock
-
-    clock-names:
-      items:
-        - const: ref_clk
-        - const: sata_clk
-        - const: pcie_clk
-        - const: eth_clk
-
-properties:
-  compatible:
-    enum:
-      - baikal,bt1-ccu-axi
-      - baikal,bt1-ccu-sys
-
-  reg:
-    maxItems: 1
-
-  "#clock-cells":
-    const: 1
-
-  "#reset-cells":
-    const: 1
-
-  clocks:
-    minItems: 3
-    maxItems: 4
-
-  clock-names:
-    minItems: 3
-    maxItems: 4
-
-additionalProperties: false
-
-required:
-  - compatible
-  - "#clock-cells"
-  - clocks
-  - clock-names
-
-examples:
-  # AXI-bus Clock Control Unit node:
-  - |
-    #include <dt-bindings/clock/bt1-ccu.h>
-
-    clock-controller@1f04d030 {
-      compatible = "baikal,bt1-ccu-axi";
-      reg = <0x1f04d030 0x030>;
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-
-      clocks = <&ccu_pll CCU_SATA_PLL>,
-               <&ccu_pll CCU_PCIE_PLL>,
-               <&ccu_pll CCU_ETH_PLL>;
-      clock-names = "sata_clk", "pcie_clk", "eth_clk";
-    };
-  # System Devices Clock Control Unit node:
-  - |
-    #include <dt-bindings/clock/bt1-ccu.h>
-
-    clock-controller@1f04d060 {
-      compatible = "baikal,bt1-ccu-sys";
-      reg = <0x1f04d060 0x0a0>;
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-
-      clocks = <&clk25m>,
-               <&ccu_pll CCU_SATA_PLL>,
-               <&ccu_pll CCU_PCIE_PLL>,
-               <&ccu_pll CCU_ETH_PLL>;
-      clock-names = "ref_clk", "sata_clk", "pcie_clk",
-                    "eth_clk";
-    };
-  # Required Clock Control Unit PLL node:
-  - |
-    ccu_pll: clock-controller@1f04d000 {
-      compatible = "baikal,bt1-ccu-pll";
-      reg = <0x1f04d000 0x028>;
-      #clock-cells = <1>;
-
-      clocks = <&clk25m>;
-      clock-names = "ref_clk";
-    };
-...
diff --git a/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml b/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml
deleted file mode 100644
index 7f8d982..0000000
--- a/Documentation/devicetree/bindings/clock/baikal,bt1-ccu-pll.yaml
+++ /dev/null
@@ -1,131 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-# Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/baikal,bt1-ccu-pll.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: Baikal-T1 Clock Control Unit PLL
-
-maintainers:
-  - Serge Semin <fancer.lancer@gmail.com>
-
-description: |
-  Clocks Control Unit is the core of Baikal-T1 SoC System Controller
-  responsible for the chip subsystems clocking and resetting. The CCU is
-  connected with an external fixed rate oscillator, which signal is transformed
-  into clocks of various frequencies and then propagated to either individual
-  IP-blocks or to groups of blocks (clock domains). The transformation is done
-  by means of PLLs and gateable/non-gateable dividers embedded into the CCU.
-  It's logically divided into the next components:
-  1) External oscillator (normally XTAL's 25 MHz crystal oscillator, but
-     in general can provide any frequency supported by the CCU PLLs).
-  2) PLLs clocks generators (PLLs) - described in this binding file.
-  3) AXI-bus clock dividers (AXI).
-  4) System devices reference clock dividers (SYS).
-  which are connected with each other as shown on the next figure:
-
-          +---------------+
-          | Baikal-T1 CCU |
-          |   +----+------|- MIPS P5600 cores
-          | +-|PLLs|------|- DDR controller
-          | | +----+      |
-  +----+  | |  |  |       |
-  |XTAL|--|-+  |  | +---+-|
-  +----+  | |  |  +-|AXI|-|- AXI-bus
-          | |  |    +---+-|
-          | |  |          |
-          | |  +----+---+-|- APB-bus
-          | +-------|SYS|-|- Low-speed Devices
-          |         +---+-|- High-speed Devices
-          +---------------+
-
-  Each CCU sub-block is represented as a separate dts-node and has an
-  individual driver to be bound with.
-
-  In order to create signals of wide range frequencies the external oscillator
-  output is primarily connected to a set of CCU PLLs. There are five PLLs
-  to create a clock for the MIPS P5600 cores, the embedded DDR controller,
-  SATA, Ethernet and PCIe domains. The last three domains though named by the
-  biggest system interfaces in fact include nearly all of the rest SoC
-  peripherals. Each of the PLLs is based on True Circuits TSMC CLN28HPM core
-  with an interface wrapper (so called safe PLL' clocks switcher) to simplify
-  the PLL configuration procedure. The PLLs work as depicted on the next
-  diagram:
-
-      +--------------------------+
-      |                          |
-      +-->+---+    +---+   +---+ |  +---+   0|\
-  CLKF--->|/NF|--->|PFD|...|VCO|-+->|/OD|--->| |
-          +---+ +->+---+   +---+ /->+---+    | |--->CLKOUT
-  CLKOD---------C----------------+          1| |
-       +--------C--------------------------->|/
-       |        |                             ^
-  Rclk-+->+---+ |                             |
-  CLKR--->|/NR|-+                             |
-          +---+                               |
-  BYPASS--------------------------------------+
-  BWADJ--->
-
-  where Rclk is the reference clock coming  from XTAL, NR - reference clock
-  divider, NF - PLL clock multiplier, OD - VCO output clock divider, CLKOUT -
-  output clock, BWADJ is the PLL bandwidth adjustment parameter. At this moment
-  the binding supports the PLL dividers configuration in accordance with a
-  requested rate, while bypassing and bandwidth adjustment settings can be
-  added in future if it gets to be necessary.
-
-  The PLLs CLKOUT is then either directly connected with the corresponding
-  clocks consumer (like P5600 cores or DDR controller) or passed over a CCU
-  divider to create a signal required for the clock domain.
-
-  The CCU PLL dts-node uses the common clock bindings with no custom
-  parameters. The list of exported clocks can be found in
-  'include/dt-bindings/clock/bt1-ccu.h'. Since CCU PLL is a part of the
-  Baikal-T1 SoC System Controller its DT node is supposed to be a child of
-  later one.
-
-properties:
-  compatible:
-    const: baikal,bt1-ccu-pll
-
-  reg:
-    maxItems: 1
-
-  "#clock-cells":
-    const: 1
-
-  clocks:
-    description: External reference clock
-    maxItems: 1
-
-  clock-names:
-    const: ref_clk
-
-additionalProperties: false
-
-required:
-  - compatible
-  - "#clock-cells"
-  - clocks
-  - clock-names
-
-examples:
-  # Clock Control Unit PLL node:
-  - |
-    clock-controller@1f04d000 {
-      compatible = "baikal,bt1-ccu-pll";
-      reg = <0x1f04d000 0x028>;
-      #clock-cells = <1>;
-
-      clocks = <&clk25m>;
-      clock-names = "ref_clk";
-    };
-  # Required external oscillator:
-  - |
-    clk25m: clock-oscillator-25m {
-      compatible = "fixed-clock";
-      #clock-cells = <0>;
-      clock-frequency = <25000000>;
-      clock-output-names = "clk25m";
-    };
-...
diff --git a/Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml b/Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml
new file mode 100644
index 0000000..3125ae5
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/eswin,eic7700-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Eswin EIC7700 SoC clock controller
+
+maintainers:
+  - Yifeng Huang <huangyifeng@eswincomputing.com>
+  - Xuyang Dong <dongxuyang@eswincomputing.com>
+
+description:
+  The clock controller generates and supplies clock to all the modules
+  for eic7700 SoC.
+
+properties:
+  compatible:
+    const: eswin,eic7700-clock
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: External 24MHz oscillator clock
+
+  '#clock-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@51828000 {
+        compatible = "eswin,eic7700-clock";
+        reg = <0x51828000 0x300>;
+        clocks = <&xtal24m>;
+        #clock-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
index 3bca9d1..041a63f 100644
--- a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
@@ -10,10 +10,10 @@
   - Michael Walle <michael@walle.cc>
 
 description: |
-  It is possible to use the BCLK pin of a SAI module as a generic clock
-  output. Some SoC are very constrained in their pin multiplexer
-  configuration. Eg. pins can only be changed groups. For example, on the
-  LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
+  It is possible to use the BCLK or MCLK pin of a SAI module as a generic
+  clock output. Some SoC are very constrained in their pin multiplexer
+  configuration. E.g. pins can only be changed in groups. For example, on
+  the LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
   the second pins are wasted. Using this binding it is possible to use the
   clock of the second SAI as a MCLK clock for an audio codec, for example.
 
@@ -21,16 +21,45 @@
 
 properties:
   compatible:
-    const: fsl,vf610-sai-clock
+    oneOf:
+      - items:
+          - enum:
+              - fsl,imx8mm-sai-clock
+              - fsl,imx8mn-sai-clock
+              - fsl,imx8mp-sai-clock
+          - const: fsl,imx8mq-sai-clock
+      - items:
+          - enum:
+              - fsl,imx8mq-sai-clock
+              - fsl,vf610-sai-clock
 
   reg:
     maxItems: 1
 
   clocks:
-    maxItems: 1
+    minItems: 1
+    maxItems: 2
+
+  clock-names:
+    minItems: 1
+    items:
+      - const: bus
+      - const: mclk1
 
   '#clock-cells':
-    const: 0
+    maximum: 1
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: fsl,vf610-sai-clock
+    then:
+      properties:
+        clocks:
+          maxItems: 1
+        clock-names: false
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.yaml b/Documentation/devicetree/bindings/clock/imx6q-clock.yaml
index cd3c04c..0e6febe 100644
--- a/Documentation/devicetree/bindings/clock/imx6q-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx6q-clock.yaml
@@ -29,20 +29,24 @@
     const: 1
 
   clocks:
+    minItems: 5
     items:
       - description: 24m osc
       - description: 32k osc
       - description: ckih1 clock input
       - description: anaclk1 clock input
       - description: anaclk2 clock input
+      - description: clock input from enet ref pad
 
   clock-names:
+    minItems: 5
     items:
       - const: osc
       - const: ckil
       - const: ckih1
       - const: anaclk1
       - const: anaclk2
+      - const: enet_ref_pad
 
   fsl,pmic-stby-poweroff:
     $ref: /schemas/types.yaml#/definitions/flag
diff --git a/Documentation/devicetree/bindings/clock/imx6ul-clock.yaml b/Documentation/devicetree/bindings/clock/imx6ul-clock.yaml
index d57e18a..0350027 100644
--- a/Documentation/devicetree/bindings/clock/imx6ul-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/imx6ul-clock.yaml
@@ -29,18 +29,22 @@
     const: 1
 
   clocks:
+    minItems: 4
     items:
       - description: 32k osc
       - description: 24m osc
       - description: ipp_di0 clock input
       - description: ipp_di1 clock input
+      - description: clock input from enet1 ref pad
 
   clock-names:
+    minItems: 4
     items:
       - const: ckil
       - const: osc
       - const: ipp_di0
       - const: ipp_di1
+      - const: enet1_ref_pad
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/clock/qcom,eliza-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,eliza-dispcc.yaml
new file mode 100644
index 0000000..0935ec1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,eliza-dispcc.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,eliza-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Display Clock & Reset Controller for Qualcomm Eliza SoC
+
+maintainers:
+  - Bjorn Andersson <andersson@kernel.org>
+  - Konrad Dybcio <konradybcio@kernel.org>
+  - Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+
+description: |
+  Display clock control module provides the clocks, resets and power
+  domains on Qualcomm Eliza SoC platform.
+
+  See also:
+  - include/dt-bindings/clock/qcom,eliza-dispcc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,eliza-dispcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board Always On XO source
+      - description: Display's AHB clock
+      - description: sleep clock
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY0
+      - description: Byte clock from DSI PHY1
+      - description: Pixel clock from DSI PHY1
+      - description: Link clock from DP PHY0
+      - description: VCO DIV clock from DP PHY0
+      - description: Link clock from DP PHY1
+      - description: VCO DIV clock from DP PHY1
+      - description: Link clock from DP PHY2
+      - description: VCO DIV clock from DP PHY2
+      - description: Link clock from DP PHY3
+      - description: VCO DIV clock from DP PHY3
+      - description: HDMI link clock from HDMI PHY
+
+  power-domains:
+    maxItems: 1
+
+  required-opps:
+    maxItems: 1
+
+required:
+  - compatible
+  - clocks
+  - '#power-domain-cells'
+
+allOf:
+  - $ref: qcom,gcc.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,dsi-phy-28nm.h>
+    #include <dt-bindings/clock/qcom,eliza-gcc.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom,rpmhpd.h>
+    clock-controller@af00000 {
+        compatible = "qcom,eliza-dispcc";
+        reg = <0x0af00000 0x20000>;
+        clocks = <&bi_tcxo_div2>,
+                 <&bi_tcxo_ao_div2>,
+                 <&gcc GCC_DISP_AHB_CLK>,
+                 <&sleep_clk>,
+                 <&dsi0_phy DSI_BYTE_PLL_CLK>,
+                 <&dsi0_phy DSI_PIXEL_PLL_CLK>,
+                 <&dsi1_phy DSI_BYTE_PLL_CLK>,
+                 <&dsi1_phy DSI_PIXEL_PLL_CLK>,
+                 <&dp0_phy 0>,
+                 <&dp0_phy 1>,
+                 <&dp1_phy 0>,
+                 <&dp1_phy 1>,
+                 <&dp2_phy 0>,
+                 <&dp2_phy 1>,
+                 <&dp3_phy 0>,
+                 <&dp3_phy 1>,
+                 <&hdmi_phy>;
+
+        #clock-cells = <1>;
+        #power-domain-cells = <1>;
+        #reset-cells = <1>;
+
+        power-domains = <&rpmhpd RPMHPD_MMCX>;
+        required-opps = <&rpmhpd_opp_low_svs>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,glymur-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,glymur-dispcc.yaml
index 45f027c..9de4ba7 100644
--- a/Documentation/devicetree/bindings/clock/qcom,glymur-dispcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,glymur-dispcc.yaml
@@ -4,14 +4,14 @@
 $id: http://devicetree.org/schemas/clock/qcom,glymur-dispcc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Qualcomm Display Clock & Reset Controller on GLYMUR
+title: Qualcomm Display Clock & Reset Controller on Glymur SoC
 
 maintainers:
   - Taniya Das <taniya.das@oss.qualcomm.com>
 
 description: |
   Qualcomm display clock control module which supports the clocks, resets and
-  power domains for the MDSS instances on GLYMUR SoC.
+  power domains for the MDSS instances on Glymur SoC.
 
   See also:
     include/dt-bindings/clock/qcom,dispcc-glymur.h
diff --git a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
index 817d511..de338c0 100644
--- a/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,ipq9574-cmn-pll.yaml
@@ -26,6 +26,8 @@
     enum:
       - qcom,ipq5018-cmn-pll
       - qcom,ipq5424-cmn-pll
+      - qcom,ipq6018-cmn-pll
+      - qcom,ipq8074-cmn-pll
       - qcom,ipq9574-cmn-pll
 
   reg:
diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml
index 5490a97..466c884 100644
--- a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml
@@ -20,7 +20,9 @@
 properties:
   compatible:
     enum:
+      - qcom,glymur-gxclkctl
       - qcom,kaanapali-gxclkctl
+      - qcom,sm8750-gxclkctl
 
   power-domains:
     description:
diff --git a/Documentation/devicetree/bindings/clock/qcom,milos-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,milos-gcc.yaml
index 60f1c8ca..c65a6ad 100644
--- a/Documentation/devicetree/bindings/clock/qcom,milos-gcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,milos-gcc.yaml
@@ -35,9 +35,14 @@
       - description: UFS Phy Tx symbol 0 clock source
       - description: USB3 Phy wrapper pipe clock source
 
+  power-domains:
+    items:
+      - description: CX domain
+
 required:
   - compatible
   - clocks
+  - power-domains
   - '#power-domain-cells'
 
 allOf:
@@ -48,6 +53,7 @@
 examples:
   - |
     #include <dt-bindings/clock/qcom,rpmh.h>
+    #include <dt-bindings/power/qcom,rpmhpd.h>
     clock-controller@100000 {
         compatible = "qcom,milos-gcc";
         reg = <0x00100000 0x1f4200>;
@@ -59,6 +65,7 @@
                  <&ufs_mem_phy 1>,
                  <&ufs_mem_phy 2>,
                  <&usb_1_qmpphy>;
+        power-domains = <&rpmhpd RPMHPD_CX>;
         #clock-cells = <1>;
         #reset-cells = <1>;
         #power-domain-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/qcom,nord-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,nord-gcc.yaml
new file mode 100644
index 0000000..e351367
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,nord-gcc.yaml
@@ -0,0 +1,58 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,nord-gcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller on Nord SoC
+
+maintainers:
+  - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+  Qualcomm global clock control module provides the clocks, resets and power
+  domains on Nord SoC.
+
+  See also: include/dt-bindings/clock/qcom,nord-gcc.h
+
+properties:
+  compatible:
+    const: qcom,nord-gcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+      - description: PCIE A Pipe clock source
+      - description: PCIE B Pipe clock source
+      - description: PCIE C Pipe clock source
+      - description: PCIE D 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,nord-gcc";
+      reg = <0x00100000 0x1f4200>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>,
+               <&pcie_a_pipe_clk>,
+               <&pcie_b_pipe_clk>,
+               <&pcie_c_pipe_clk>,
+               <&pcie_d_pipe_clk>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,nord-negcc.yaml b/Documentation/devicetree/bindings/clock/qcom,nord-negcc.yaml
new file mode 100644
index 0000000..749389f
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,nord-negcc.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,nord-negcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global North East Clock & Reset Controller on Nord SoC
+
+maintainers:
+  - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+  Qualcomm global clock control (NE) module provides the clocks, resets
+  and power domains on Nord SoC.
+
+  See also: include/dt-bindings/clock/qcom,nord-negcc.h
+
+properties:
+  compatible:
+    const: qcom,nord-negcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+      - 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 sec wrapper pipe 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@8900000 {
+      compatible = "qcom,nord-negcc";
+      reg = <0x08900000 0xf4200>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>,
+               <&ufs_phy_rx_symbol_0_clk>,
+               <&ufs_phy_rx_symbol_1_clk>,
+               <&ufs_phy_tx_symbol_0_clk>,
+               <&usb3_phy_sec_pipe_clk>,
+               <&usb3_phy_pipe_clk>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,nord-nwgcc.yaml b/Documentation/devicetree/bindings/clock/qcom,nord-nwgcc.yaml
new file mode 100644
index 0000000..ce33f96
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/qcom,nord-nwgcc.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,nord-nwgcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global North West and South East  Clock & Reset Controller
+       on Nord SoC
+
+maintainers:
+  - Taniya Das <taniya.das@oss.qualcomm.com>
+
+description: |
+  Qualcomm global clock control (NW, SE) module provides the clocks, resets
+  and power domains on Nord SoC.
+
+  See also:
+    include/dt-bindings/clock/qcom,nord-nwgcc.h
+    include/dt-bindings/clock/qcom,nord-segcc.h
+
+properties:
+  compatible:
+    enum:
+      - qcom,nord-nwgcc
+      - qcom,nord-segcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep 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@8b00000 {
+      compatible = "qcom,nord-nwgcc";
+      reg = <0x08b00000 0xf4200>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
index 9690169..a2c404a 100644
--- a/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
@@ -21,6 +21,7 @@
       - qcom,glymur-rpmh-clk
       - qcom,kaanapali-rpmh-clk
       - qcom,milos-rpmh-clk
+      - qcom,nord-rpmh-clk
       - qcom,qcs615-rpmh-clk
       - qcom,qdu1000-rpmh-clk
       - qcom,sa8775p-rpmh-clk
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml
index 6feaa32..fdbdf60 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml
@@ -8,12 +8,14 @@
 
 maintainers:
   - Konrad Dybcio <konradybcio@kernel.org>
+  - Taniya Das <taniya.das@oss.qualcomm.com>
 
 description: |
   Qualcomm graphics clock control module provides the clocks, resets and power
   domains on Qualcomm SoCs.
 
-  See also::
+  See also:
+    include/dt-bindings/clock/qcom,glymur-gpucc.h
     include/dt-bindings/clock/qcom,kaanapali-gpucc.h
     include/dt-bindings/clock/qcom,milos-gpucc.h
     include/dt-bindings/clock/qcom,sar2130p-gpucc.h
@@ -22,11 +24,13 @@
     include/dt-bindings/clock/qcom,sm8550-gpucc.h
     include/dt-bindings/reset/qcom,sm8450-gpucc.h
     include/dt-bindings/reset/qcom,sm8650-gpucc.h
+    include/dt-bindings/reset/qcom,sm8750-gpucc.h
     include/dt-bindings/reset/qcom,x1e80100-gpucc.h
 
 properties:
   compatible:
     enum:
+      - qcom,glymur-gpucc
       - qcom,kaanapali-gpucc
       - qcom,milos-gpucc
       - qcom,sar2130p-gpucc
@@ -35,6 +39,7 @@
       - qcom,sm8475-gpucc
       - qcom,sm8550-gpucc
       - qcom,sm8650-gpucc
+      - qcom,sm8750-gpucc
       - qcom,x1e80100-gpucc
       - qcom,x1p42100-gpucc
 
@@ -44,6 +49,16 @@
       - description: GPLL0 main branch source
       - description: GPLL0 div branch source
 
+  power-domains:
+    items:
+      - description: A phandle to the MX power-domain
+      - description: A phandle to the CX power-domain
+
+  required-opps:
+    items:
+      - description: A phandle to an OPP node describing MX performance points
+      - description: A phandle to an OPP node describing CX performance points
+
 required:
   - compatible
   - clocks
@@ -51,6 +66,16 @@
 
 allOf:
   - $ref: qcom,gcc.yaml#
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,sm8750-gpucc
+    then:
+      required:
+        - power-domains
+        - required-opps
 
 unevaluatedProperties: false
 
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml
index e6beebd..7bbf120 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml
@@ -15,6 +15,7 @@
   domains on SM8450.
 
   See also:
+    include/dt-bindings/clock/qcom,glymur-videocc.h
     include/dt-bindings/clock/qcom,kaanapali-videocc.h
     include/dt-bindings/clock/qcom,sm8450-videocc.h
     include/dt-bindings/clock/qcom,sm8650-videocc.h
@@ -23,6 +24,7 @@
 properties:
   compatible:
     enum:
+      - qcom,glymur-videocc
       - qcom,kaanapali-videocc
       - qcom,sm8450-videocc
       - qcom,sm8475-videocc
@@ -63,6 +65,7 @@
         compatible:
           contains:
             enum:
+              - qcom,glymur-videocc
               - qcom,kaanapali-videocc
               - qcom,sm8450-videocc
               - qcom,sm8550-videocc
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml
index ae9aef0..1ccdf4b 100644
--- a/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml
+++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-tcsr.yaml
@@ -17,6 +17,7 @@
   See also:
   - include/dt-bindings/clock/qcom,eliza-tcsr.h
   - include/dt-bindings/clock/qcom,glymur-tcsr.h
+  - include/dt-bindings/clock/qcom,nord-tcsrcc.h
   - include/dt-bindings/clock/qcom,sm8550-tcsr.h
   - include/dt-bindings/clock/qcom,sm8650-tcsr.h
   - include/dt-bindings/clock/qcom,sm8750-tcsr.h
@@ -29,6 +30,7 @@
           - qcom,glymur-tcsr
           - qcom,kaanapali-tcsr
           - qcom,milos-tcsr
+          - qcom,nord-tcsrcc
           - qcom,sar2130p-tcsr
           - qcom,sm8550-tcsr
           - qcom,sm8650-tcsr
diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
index 1318720..6b1fc61a 100644
--- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml
@@ -35,6 +35,7 @@
       - samsung,exynosautov920-cmu-cpucl0
       - samsung,exynosautov920-cmu-cpucl1
       - samsung,exynosautov920-cmu-cpucl2
+      - samsung,exynosautov920-cmu-g3d
       - samsung,exynosautov920-cmu-hsi0
       - samsung,exynosautov920-cmu-hsi1
       - samsung,exynosautov920-cmu-hsi2
@@ -287,6 +288,26 @@
             - const: oscclk
             - const: noc
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: samsung,exynosautov920-cmu-g3d
+
+    then:
+      properties:
+        clocks:
+          items:
+            - description: External reference clock (38.4 MHz)
+            - description: CMU_G3D SWITCH clock (from CMU_TOP)
+            - description: CMU_G3D NOCP clock (from CMU_TOP)
+
+        clock-names:
+          items:
+            - const: oscclk
+            - const: switch
+            - const: nocp
+
 required:
   - compatible
   - "#clock-cells"
diff --git a/Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml b/Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml
new file mode 100644
index 0000000..7fa1652
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.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/tenstorrent,atlantis-prcm-rcpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Tenstorrent Atlantis PRCM (Power, Reset, Clock Management) Module
+
+maintainers:
+  - Anirudh Srinivasan <asrinivasan@oss.tenstorrent.com>
+
+description:
+  Multifunctional register block found in Tenstorrent Atlantis SoC whose main
+  function is to control clocks and resets. This block is instantiated multiple
+  times in the SoC, each block controls clock and resets for a different
+  subsystem. RCPU prcm serves low speed IO interfaces.
+
+properties:
+  compatible:
+    enum:
+      - tenstorrent,atlantis-prcm-rcpu
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 1
+    description:
+      See <dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h> for valid indices.
+
+  "#reset-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - "#clock-cells"
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller@a8000000 {
+      compatible = "tenstorrent,atlantis-prcm-rcpu";
+      reg = <0xa8000000 0x10000>;
+      clocks = <&osc_24m>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
diff --git a/Documentation/devicetree/bindings/connector/usb-connector.yaml b/Documentation/devicetree/bindings/connector/usb-connector.yaml
index d97b29e..8ca0292 100644
--- a/Documentation/devicetree/bindings/connector/usb-connector.yaml
+++ b/Documentation/devicetree/bindings/connector/usb-connector.yaml
@@ -300,6 +300,40 @@
     $ref: /schemas/types.yaml#/definitions/uint8-array
     maxItems: 4
 
+  sink-load-step:
+    description: Indicates the preferred load step slew rate in mA/usec for
+      the port (in sink mode). This property is defined in "6.5.13.7" of
+      "USB Power Delivery Specification Revision 3.1 Version 1.8".
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [150, 500]
+    default: 150
+
+  sink-load-characteristics:
+    description: Indicates the port's (in sink mode) preferred load
+      characteristics. Users can leverage SINK_LOAD_CHAR() defined in
+      dt-bindings/usb/pd.h to populate this field. This property is defined in
+      "6.5.13.8" of "USB Power Delivery Specification Revision 3.1 Version 1.8".
+    $ref: /schemas/types.yaml#/definitions/uint16
+
+  sink-compliance:
+    description: Represents the types of sources the sink device has been tested
+      and certified with. This property is defined in "6.5.13.9" of
+      "USB Power Delivery Specification Revision 3.1 Version 1.8"
+      Bit 0 when set indicates it has been tested on LPS compliant source
+      Bit 1 when set indicates it has been tested on PS1 compliant source
+      Bit 2 when set indicates it has been tested on PS2 compliant source
+    $ref: /schemas/types.yaml#/definitions/uint8
+    maximum: 7
+
+  charging-adapter-pdp-milliwatt:
+    description: This corresponds to the Power Delivery Profile rating of the
+      charging adapter shipped or recommended for use with the connector port.
+      This property is a requirement to infer the USB PD property
+      "SPR Sink Operational PDP" given in "6.5.13.14" of
+      "USB Power Delivery Specification Revision 3.1 Version 1.8".
+    minimum: 0
+    maximum: 100000
+
 dependencies:
   pd-disable: [typec-power-opmode]
   sink-vdos-v1: [ sink-vdos ]
@@ -331,8 +365,9 @@
           "Universal Serial Bus Power Delivery Specification" chapter 6.4.1.3
           Sink Capabilities Message, the order of each entry(PDO) should follow the
           PD spec chapter 6.4.1. Required for power sink and power dual role. User
-          can specify the sink PDO array via PDO_FIXED/BATT/VAR/PPS_APDO() defined
-          in dt-bindings/usb/pd.h.
+          can specify the sink PDO array via
+          PDO_FIXED/BATT/VAR/PPS_APDO/SPR_AVS_SNK_APDO() defined in
+          dt-bindings/usb/pd.h.
         minItems: 1
         maxItems: 7
         $ref: /schemas/types.yaml#/definitions/uint32-array
diff --git a/Documentation/devicetree/bindings/display/apple,h7-display-pipe-mipi.yaml b/Documentation/devicetree/bindings/display/apple,h7-display-pipe-mipi.yaml
index 5e6da66..d7c822d 100644
--- a/Documentation/devicetree/bindings/display/apple,h7-display-pipe-mipi.yaml
+++ b/Documentation/devicetree/bindings/display/apple,h7-display-pipe-mipi.yaml
@@ -7,7 +7,7 @@
 title: Apple pre-DCP display controller MIPI interface
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description:
   The MIPI controller part of the pre-DCP Apple display controller
diff --git a/Documentation/devicetree/bindings/display/apple,h7-display-pipe.yaml b/Documentation/devicetree/bindings/display/apple,h7-display-pipe.yaml
index 102fb18..571fa32 100644
--- a/Documentation/devicetree/bindings/display/apple,h7-display-pipe.yaml
+++ b/Documentation/devicetree/bindings/display/apple,h7-display-pipe.yaml
@@ -7,7 +7,7 @@
 title: Apple pre-DCP display controller
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description:
   A secondary display controller used to drive the "touchbar" on
diff --git a/Documentation/devicetree/bindings/display/panel/apple,summit.yaml b/Documentation/devicetree/bindings/display/panel/apple,summit.yaml
index f081755..1c1ba59 100644
--- a/Documentation/devicetree/bindings/display/panel/apple,summit.yaml
+++ b/Documentation/devicetree/bindings/display/panel/apple,summit.yaml
@@ -7,7 +7,7 @@
 title: Apple "Summit" display panel
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description:
   An OLED panel used as a touchbar on certain Apple laptops.
diff --git a/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
index 072b3c0..79f88b5 100644
--- a/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
+++ b/Documentation/devicetree/bindings/extcon/extcon-ptn5150.yaml
@@ -42,6 +42,9 @@
     description:
       A port node to link the usb controller for the dual role switch.
 
+  connector:
+    $ref: /schemas/connector/usb-connector.yaml#
+
 required:
   - compatible
   - interrupts
diff --git a/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml b/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml
index 3f4bbd5..fe9b14a 100644
--- a/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/trivial-gpio.yaml
@@ -27,7 +27,6 @@
           - gateworks,pld-gpio
           - ibm,ppc4xx-gpio
           - loongson,ls1x-gpio
-          - maxim,max77620
           - nintendo,hollywood-gpio
           - nxp,pca9570
           - nxp,pca9571
@@ -86,7 +85,6 @@
         compatible:
           contains:
             enum:
-              - maxim,max77620
               - rockchip,rk3328-grf-gpio
               - ti,lp3943-gpio
               - ti,palmas-gpio
diff --git a/Documentation/devicetree/bindings/gpu/apple,agx.yaml b/Documentation/devicetree/bindings/gpu/apple,agx.yaml
index 05af942..59989d8 100644
--- a/Documentation/devicetree/bindings/gpu/apple,agx.yaml
+++ b/Documentation/devicetree/bindings/gpu/apple,agx.yaml
@@ -7,7 +7,7 @@
 title: Apple SoC GPU
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 properties:
   compatible:
diff --git a/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml b/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml
new file mode 100644
index 0000000..c11bbf8
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/cnxt,cx92755-i2c.yaml
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/cnxt,cx92755-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Conexant Digicolor I2C controller
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+maintainers:
+  - Baruch Siach <baruch@tkos.co.il>
+
+properties:
+  compatible:
+    const: cnxt,cx92755-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-frequency:
+    default: 100000
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    i2c@f0000120 {
+      compatible = "cnxt,cx92755-i2c";
+      reg = <0xf0000120 0x10>;
+      interrupts = <28>;
+      clocks = <&main_clk>;
+      clock-frequency = <100000>;
+      #address-cells = <1>;
+      #size-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt b/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt
deleted file mode 100644
index 457a098..0000000
--- a/Documentation/devicetree/bindings/i2c/i2c-digicolor.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-Conexant Digicolor I2C controller
-
-Required properties:
- - compatible: must be "cnxt,cx92755-i2c"
- - reg: physical address and length of the device registers
- - interrupts: a single interrupt specifier
- - clocks: clock for the device
- - #address-cells: should be <1>
- - #size-cells: should be <0>
-
-Optional properties:
-- clock-frequency: the desired I2C bus clock frequency in Hz; in
-  absence of this property the default value is used (100 kHz).
-
-Example:
-
-	i2c: i2c@f0000120 {
-		compatible = "cnxt,cx92755-i2c";
-		reg = <0xf0000120 0x10>;
-		interrupts = <28>;
-		clocks = <&main_clk>;
-		clock-frequency = <100000>;
-		#address-cells = <1>;
-		#size-cells = <0>;
-	};
diff --git a/Documentation/devicetree/bindings/i2c/i2c-iop3xx.txt b/Documentation/devicetree/bindings/i2c/i2c-iop3xx.txt
deleted file mode 100644
index dcc8390..0000000
--- a/Documentation/devicetree/bindings/i2c/i2c-iop3xx.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-i2c Controller on XScale platforms such as IOP3xx and IXP4xx
-
-Required properties:
-- compatible : Must be one of
-  "intel,iop3xx-i2c"
-  "intel,ixp4xx-i2c";
-- reg
-- #address-cells = <1>;
-- #size-cells = <0>;
-
-Optional properties:
-- Child nodes conforming to i2c bus binding
-
-Example:
-
-i2c@c8011000 {
-	compatible = "intel,ixp4xx-i2c";
-	reg = <0xc8011000 0x18>;
-	interrupts = <33 IRQ_TYPE_LEVEL_LOW>;
-};
diff --git a/Documentation/devicetree/bindings/i2c/intel,ixp4xx-i2c.yaml b/Documentation/devicetree/bindings/i2c/intel,ixp4xx-i2c.yaml
new file mode 100644
index 0000000..15ef510
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/intel,ixp4xx-i2c.yaml
@@ -0,0 +1,41 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i2c/intel,ixp4xx-i2c.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: I2c Controller on XScale platforms such as IOP3xx and IXP4xx
+
+maintainers:
+  - Andi Shyti <andi.shyti@kernel.org>
+
+allOf:
+  - $ref: /schemas/i2c/i2c-controller.yaml#
+
+properties:
+  compatible:
+    enum:
+      - intel,iop3xx-i2c
+      - intel,ixp4xx-i2c
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c@c8011000 {
+        compatible = "intel,ixp4xx-i2c";
+        reg = <0xc8011000 0x18>;
+        interrupts = <33 IRQ_TYPE_LEVEL_LOW>;
+    };
diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
index 399a094..7c497a3 100644
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
@@ -27,6 +27,7 @@
       - items:
           - enum:
               - qcom,kaanapali-cci
+              - qcom,milos-cci
               - qcom,qcm2290-cci
               - qcom,qcs8300-cci
               - qcom,sa8775p-cci
@@ -34,6 +35,7 @@
               - qcom,sc8280xp-cci
               - qcom,sdm670-cci
               - qcom,sdm845-cci
+              - qcom,sm6150-cci
               - qcom,sm6350-cci
               - qcom,sm8250-cci
               - qcom,sm8450-cci
@@ -251,6 +253,7 @@
           contains:
             enum:
               - qcom,sa8775p-cci
+              - qcom,sm6150-cci
               - qcom,sm8550-cci
               - qcom,sm8650-cci
               - qcom,x1e80100-cci
@@ -265,6 +268,23 @@
             - const: cpas_ahb
             - const: cci
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,milos-cci
+    then:
+      properties:
+        clocks:
+          minItems: 3
+          maxItems: 3
+        clock-names:
+          items:
+            - const: soc_ahb
+            - const: cpas_ahb
+            - const: cci
+
 additionalProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
index f9a449f..5873cfd 100644
--- a/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/realtek,rtl9301-i2c.yaml
@@ -15,6 +15,8 @@
   assigned to either I2C controller.
   RTL9310 SoCs have equal capabilities but support 12 common SDA lines which
   can be assigned to either I2C controller.
+  RTL9607C SoCs have equal capabilities but each controller only supports 1
+  SCL/SDA line.
 
 properties:
   compatible:
@@ -34,6 +36,7 @@
       - enum:
           - realtek,rtl9301-i2c
           - realtek,rtl9310-i2c
+          - realtek,rtl9607-i2c
 
   reg:
     items:
@@ -51,6 +54,9 @@
       The SCL line number of this I2C controller.
     enum: [ 0, 1 ]
 
+  clocks:
+    maxItems: 1
+
 patternProperties:
   '^i2c@[0-9ab]$':
     $ref: /schemas/i2c/i2c-controller.yaml
@@ -81,6 +87,15 @@
     then:
       patternProperties:
         '^i2c@[89ab]$': false
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: realtek,rtl9607-i2c
+    then:
+      required:
+        - realtek,scl
+        - clocks
 
 required:
   - compatible
diff --git a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml
index 6876ead..ae1f71e 100644
--- a/Documentation/devicetree/bindings/i2c/renesas,riic.yaml
+++ b/Documentation/devicetree/bindings/i2c/renesas,riic.yaml
@@ -25,6 +25,7 @@
       - items:
           - enum:
               - renesas,riic-r9a08g045   # RZ/G3S
+              - renesas,riic-r9a08g046   # RZ/G3L
               - renesas,riic-r9a09g047   # RZ/G3E
               - renesas,riic-r9a09g056   # RZ/V2N
           - const: renesas,riic-r9a09g057   # RZ/V2H(P)
diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml
index 082fdc2..467bdcb 100644
--- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml
@@ -32,8 +32,6 @@
           - const: renesas,r9a06g032-i2c  # RZ/N1D
           - const: renesas,rzn1-i2c       # RZ/N1
           - const: snps,designware-i2c
-      - description: Baikal-T1 SoC System I2C controller
-        const: baikal,bt1-sys-i2c
       - description: Mobileye EyeQ DesignWare I2C controller
         items:
           - enum:
diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
index 5896fb1..8c04c67 100644
--- a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml
@@ -14,7 +14,11 @@
 
 properties:
   compatible:
-    const: spacemit,k1-i2c
+    oneOf:
+      - items:
+          - const: spacemit,k3-i2c
+          - const: spacemit,k1-i2c
+      - const: spacemit,k1-i2c
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml b/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
index 0ba0df4..02e7349 100644
--- a/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
+++ b/Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
@@ -4,20 +4,23 @@
 $id: http://devicetree.org/schemas/iio/accel/adi,adxl372.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer
+title: Analog Devices ADXL371/ADXL372 3-Axis, +/-(200g) Digital Accelerometer
 
 maintainers:
   - Marcelo Schmitt <marcelo.schmitt@analog.com>
   - Nuno Sá <nuno.sa@analog.com>
+  - Antoniu Miclaus <antoniu.miclaus@analog.com>
 
 description: |
-  Analog Devices ADXL372 3-Axis, +/-(200g) Digital Accelerometer that supports
-  both I2C & SPI interfaces
+  Analog Devices ADXL371/ADXL372 3-Axis, +/-(200g) Digital Accelerometer that
+  supports both I2C & SPI interfaces
+    https://www.analog.com/en/products/adxl371.html
     https://www.analog.com/en/products/adxl372.html
 
 properties:
   compatible:
     enum:
+      - adi,adxl371
       - adi,adxl372
 
   reg:
diff --git a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml
index c1387e0..7f9c5ee 100644
--- a/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml
+++ b/Documentation/devicetree/bindings/iio/accel/bosch,bma255.yaml
@@ -16,25 +16,27 @@
 
 properties:
   compatible:
-    enum:
-      # bmc150-accel driver in Linux
-      - bosch,bma222
-      - bosch,bma222e
-      - bosch,bma250e
-      - bosch,bma253
-      - bosch,bma254
-      - bosch,bma255
-      - bosch,bma280
-      - bosch,bmc150_accel
-      - bosch,bmc156_accel
-      - bosch,bmi055_accel
+    oneOf:
+      - enum:
+          - bosch,bma222
+          - bosch,bma222e
+          - bosch,bma250e
+          - bosch,bma253
+          - bosch,bma254
+          - bosch,bma255
+          - bosch,bma280
+          - bosch,bmc150_accel
+          - bosch,bmc156_accel
+          - bosch,bmi055_accel
 
-      # bma180 driver in Linux
-      - bosch,bma023
-      - bosch,bma150
-      - bosch,bma180
-      - bosch,bma250
-      - bosch,smb380
+          - bosch,bma023
+          - bosch,bma150
+          - bosch,bma180
+          - bosch,bma250
+          - bosch,smb380
+      - items:
+          - const: bosch,bmx055-accel
+          - const: bosch,bmc150_accel
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml
index e22d518..08b1f9d 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml
@@ -19,6 +19,10 @@
   * https://www.analog.com/media/en/technical-documentation/data-sheets/ad4030-24-4032-24.pdf
   * https://www.analog.com/media/en/technical-documentation/data-sheets/ad4630-24_ad4632-24.pdf
   * https://www.analog.com/media/en/technical-documentation/data-sheets/ad4630-16-4632-16.pdf
+  * https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4216.pdf
+  * https://www.analog.com/media/en/technical-documentation/data-sheets/adaq4224.pdf
+
+$ref: /schemas/spi/spi-peripheral-props.yaml#
 
 properties:
   compatible:
@@ -29,6 +33,8 @@
       - adi,ad4630-24
       - adi,ad4632-16
       - adi,ad4632-24
+      - adi,adaq4216
+      - adi,adaq4224
 
   reg:
     maxItems: 1
@@ -60,6 +66,14 @@
     description:
       Internal buffered Reference. Used when ref-supply is not connected.
 
+  vddh-supply:
+    description:
+      PGIA Positive Power Supply.
+
+  vdd-fda-supply:
+    description:
+      FDA Positive Power Supply.
+
   cnv-gpios:
     description:
       The Convert Input (CNV). It initiates the sampling conversions.
@@ -70,6 +84,17 @@
       The Reset Input (/RST). Used for asynchronous device reset.
     maxItems: 1
 
+  pga-gpios:
+    description:
+      A0 and A1 pins for gain selection. For devices that have PGA configuration
+      input pins, pga-gpios should be defined.
+    minItems: 2
+    maxItems: 2
+
+  pwms:
+    description: PWM signal connected to the CNV pin.
+    maxItems: 1
+
   interrupts:
     description:
       The BUSY pin is used to signal that the conversions results are available
@@ -107,6 +132,22 @@
       properties:
         spi-rx-bus-width:
           maxItems: 1
+  # ADAQ devices require a gain property to indicate how hardware PGA is set
+  - if:
+      properties:
+        compatible:
+          contains:
+            pattern: ^adi,adaq
+    then:
+      required:
+        - vddh-supply
+        - vdd-fda-supply
+        - pga-gpios
+      properties:
+        ref-supply: false
+    else:
+      properties:
+        pga-gpios: false
 
 examples:
   - |
@@ -148,3 +189,26 @@
             reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
         };
     };
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        adc@0 {
+            compatible = "adi,adaq4216";
+            reg = <0>;
+            spi-max-frequency = <80000000>;
+            vdd-5v-supply = <&supply_5V>;
+            vdd-1v8-supply = <&supply_1_8V>;
+            vio-supply = <&supply_1_8V>;
+            refin-supply = <&refin_sup>;
+            vddh-supply = <&vddh>;
+            vdd-fda-supply = <&vdd_fda>;
+            cnv-gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
+            reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+            pga-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>,
+                        <&gpio0 3 GPIO_ACTIVE_HIGH>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
index ccd6a0a..79df269 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
@@ -27,10 +27,13 @@
     enum:
       - adi,ad4080
       - adi,ad4081
+      - adi,ad4082
       - adi,ad4083
       - adi,ad4084
+      - adi,ad4085
       - adi,ad4086
       - adi,ad4087
+      - adi,ad4088
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
index b91bfb1..396e1a1a 100644
--- a/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7380.yaml
@@ -62,6 +62,11 @@
   spi-cpol: true
   spi-cpha: true
 
+  spi-rx-bus-width:
+    maxItems: 4
+    items:
+      maximum: 1
+
   vcc-supply:
     description: A 3V to 3.6V supply that powers the chip.
 
@@ -160,6 +165,23 @@
 unevaluatedProperties: false
 
 allOf:
+  # 2-channel chips only have two SDO lines
+  - if:
+      properties:
+        compatible:
+          enum:
+            - adi,ad7380
+            - adi,ad7381
+            - adi,ad7383
+            - adi,ad7384
+            - adi,ad7386
+            - adi,ad7387
+            - adi,ad7388
+    then:
+      properties:
+        spi-rx-bus-width:
+          maxItems: 2
+
   # pseudo-differential chips require common mode voltage supplies,
   # true differential chips don't use them
   - if:
@@ -284,6 +306,7 @@
             spi-cpol;
             spi-cpha;
             spi-max-frequency = <80000000>;
+            spi-rx-bus-width = <1>, <1>, <1>, <1>;
 
             interrupts = <27 IRQ_TYPE_EDGE_FALLING>;
             interrupt-parent = <&gpio0>;
diff --git a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml
index bb9825e..70ab4e1 100644
--- a/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/amlogic,meson-saradc.yaml
@@ -27,7 +27,11 @@
               - amlogic,meson-gxm-saradc
               - amlogic,meson-axg-saradc
               - amlogic,meson-g12a-saradc
+          # Usage of this generic fallback is not allowed for new devices
           - const: amlogic,meson-saradc
+      - items:
+          - const: amlogic,meson-s4-saradc
+          - const: amlogic,meson-g12a-saradc
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml
index 5cc6a96..c884b6e 100644
--- a/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/lltc,ltc2497.yaml
@@ -11,6 +11,12 @@
   - Liam Beguin <liambeguin@gmail.com>
 
 description: |
+  LTC2305:
+    low noise, low power, 2-channel, 12-bit successive approximation ADC with an
+    I2C compatible serial interface.
+
+    https://www.analog.com/media/en/technical-documentation/data-sheets/23015fb.pdf
+
   LTC2309:
     low noise, low power, 8-channel, 12-bit successive approximation ADC with an
     I2C compatible serial interface.
@@ -28,6 +34,7 @@
 properties:
   compatible:
     enum:
+      - lltc,ltc2305
       - lltc,ltc2309
       - lltc,ltc2497
       - lltc,ltc2499
diff --git a/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
index 9ceb6f1..1f77da7 100644
--- a/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
@@ -19,6 +19,7 @@
     enum:
       - motorola,cpcap-adc
       - motorola,mapphone-cpcap-adc
+      - motorola,mot-cpcap-adc
 
   interrupts:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml
new file mode 100644
index 0000000..149f4af
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-adc5-gen3.yaml
@@ -0,0 +1,151 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-adc5-gen3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm's SPMI PMIC ADC5 Gen3
+
+maintainers:
+  - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
+
+description: |
+  SPMI PMIC5 Gen3 voltage ADC (ADC) provides interface to clients to read
+  voltage. It is a 16-bit sigma-delta ADC. It also performs the same thermal
+  monitoring function as the existing ADC_TM devices.
+
+  The interface is implemented on SDAM (Shared Direct Access Memory) peripherals
+  on the master PMIC rather than a dedicated ADC peripheral. The number of PMIC
+  SDAM peripherals allocated for ADC is not correlated with the PMIC used, it is
+  programmed in FW (PBS) and is fixed per SOC, based on the SOC requirements.
+  All boards using a particular (SOC + master PMIC) combination will have the
+  same number of ADC SDAMs supported on that PMIC.
+
+properties:
+  compatible:
+    const: qcom,spmi-adc5-gen3
+
+  reg:
+    items:
+      - description: SDAM0 base address in the SPMI PMIC register map
+      - description: SDAM1 base address
+    minItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 0
+
+  "#io-channel-cells":
+    const: 1
+
+  "#thermal-sensor-cells":
+    const: 1
+
+  interrupts:
+    items:
+      - description: SDAM0 end of conversion (EOC) interrupt
+      - description: SDAM1 EOC interrupt
+    minItems: 1
+
+patternProperties:
+  "^channel@[0-9a-f]+$":
+    type: object
+    unevaluatedProperties: false
+    $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml
+    description:
+      Represents the external channels which are connected to the ADC.
+
+    properties:
+      qcom,decimation:
+        enum: [ 85, 340, 1360 ]
+        default: 1360
+
+      qcom,hw-settle-time:
+        enum: [ 15, 100, 200, 300, 400, 500, 600, 700,
+                1000, 2000, 4000, 8000, 16000, 32000, 64000, 128000 ]
+        default: 15
+
+      qcom,avg-samples:
+        enum: [ 1, 2, 4, 8, 16 ]
+        default: 1
+
+      qcom,adc-tm:
+        description:
+          ADC_TM is a threshold monitoring feature in HW which can be enabled
+          on any ADC channel, to trigger an IRQ for threshold violation. In
+          earlier ADC generations, it was implemented in a separate device
+          (documented in Documentation/devicetree/bindings/thermal/qcom-spmi-adc-tm5.yaml.)
+          In Gen3, this feature can be enabled in the same ADC device for any
+          channel and threshold monitoring and IRQ triggering are handled in FW
+          (PBS) instead of another dedicated HW block.
+          This property indicates ADC_TM monitoring is done on this channel.
+        type: boolean
+
+required:
+  - compatible
+  - reg
+  - "#address-cells"
+  - "#size-cells"
+  - "#io-channel-cells"
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    pmic {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      adc@9000 {
+        compatible = "qcom,spmi-adc5-gen3";
+        reg = <0x9000>, <0x9100>;
+        interrupts = <0x0 0x90 0x1 IRQ_TYPE_EDGE_RISING>,
+                      <0x0 0x91 0x1 IRQ_TYPE_EDGE_RISING>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+        #io-channel-cells = <1>;
+        #thermal-sensor-cells = <1>;
+
+        /* PMK8550 Channel nodes */
+        channel@3 {
+          reg = <0x3>;
+          label = "pmk8550_die_temp";
+          qcom,pre-scaling = <1 1>;
+        };
+
+        channel@44 {
+          reg = <0x44>;
+          label = "pmk8550_xo_therm";
+          qcom,pre-scaling = <1 1>;
+          qcom,ratiometric;
+          qcom,hw-settle-time = <200>;
+          qcom,adc-tm;
+        };
+
+        /* PM8550 Channel nodes */
+        channel@103 {
+          reg = <0x103>;
+          label = "pm8550_die_temp";
+          qcom,pre-scaling = <1 1>;
+        };
+
+        /* PM8550B Channel nodes */
+        channel@78f {
+          reg = <0x78f>;
+          label = "pm8550b_vbat_sns_qbg";
+          qcom,pre-scaling = <1 3>;
+        };
+
+        /* PM8550VS_C Channel nodes */
+        channel@203 {
+          reg = <0x203>;
+          label = "pm8550vs_c_die_temp";
+          qcom,pre-scaling = <1 1>;
+        };
+      };
+    };
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml
new file mode 100644
index 0000000..3ae252c
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc-common.yaml
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/qcom,spmi-vadc-common.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. SPMI PMIC ADC channels
+
+maintainers:
+  - Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
+
+description:
+  This defines the common properties used to define Qualcomm VADC channels.
+
+properties:
+  reg:
+    description:
+      ADC channel number (PMIC-specific for versions after PMIC5 ADC).
+    maxItems: 1
+
+  label:
+    description:
+      ADC input of the platform as seen in the schematics.
+      For thermistor inputs connected to generic AMUX or GPIO inputs
+      these can vary across platform for the same pins. Hence select
+      the platform schematics name for this channel.
+
+  qcom,decimation:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      This parameter is used to decrease ADC sampling rate.
+      Quicker measurements can be made by reducing decimation ratio.
+
+  qcom,pre-scaling:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      Used for scaling the channel input signal before the signal is
+      fed to VADC. The configuration for this node is to know the
+      pre-determined ratio and use it for post scaling. It is a pair of
+      integers, denoting the numerator and denominator of the fraction by which
+      input signal is multiplied. For example, <1 3> indicates the signal is scaled
+      down to 1/3 of its value before ADC measurement.
+      If property is not found default value depending on chip will be used.
+    oneOf:
+      - items:
+          - const: 1
+          - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ]
+      - items:
+          - const: 10
+          - const: 81
+
+  qcom,ratiometric:
+    type: boolean
+    description: |
+      Channel calibration type.
+      - For compatible property "qcom,spmi-vadc", if this property is
+        specified VADC will use the VDD reference (1.8V) and GND for
+        channel calibration. If property is not found, channel will be
+        calibrated with 0.625V and 1.25V reference channels, also
+        known as absolute calibration.
+      - For other compatible properties, if this property is specified
+        VADC will use the VDD reference (1.875V) and GND for channel
+        calibration. If property is not found, channel will be calibrated
+        with 0V and 1.25V reference channels, also known as absolute calibration.
+
+  qcom,hw-settle-time:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Time between AMUX getting configured and the ADC starting
+      conversion. The 'hw_settle_time' is an index used from valid values
+      and programmed in hardware to achieve the hardware settling delay.
+
+  qcom,avg-samples:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: |
+      Number of samples to be used for measurement.
+      Averaging provides the option to obtain a single measurement
+      from the ADC that is an average of multiple samples. The value
+      selected is 2^(value).
+
+required:
+  - reg
+
+additionalProperties: true
diff --git a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
index b9dc04b..72188041 100644
--- a/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
@@ -15,6 +15,8 @@
   voltage. The VADC is a 15-bit sigma-delta ADC.
   SPMI PMIC5/PMIC7 voltage ADC (ADC) provides interface to clients to read
   voltage. The VADC is a 16-bit sigma-delta ADC.
+  Note that PMIC7 ADC is the generation between PMIC5 and PMIC5 Gen3 ADC,
+  it can be considered like PMIC5 Gen2.
 
 properties:
   compatible:
@@ -56,7 +58,7 @@
 patternProperties:
   "^channel@[0-9a-f]+$":
     type: object
-    additionalProperties: false
+    unevaluatedProperties: false
     description: |
       Represents the external channels which are connected to the ADC.
       For compatible property "qcom,spmi-vadc" following channels, also known as
@@ -64,79 +66,7 @@
       configuration nodes should be defined:
       VADC_REF_625MV and/or VADC_SPARE1(based on PMIC version) VADC_REF_1250MV,
       VADC_GND_REF and VADC_VDD_VADC.
-
-    properties:
-      reg:
-        maxItems: 1
-        description: |
-          ADC channel number.
-          See include/dt-bindings/iio/qcom,spmi-vadc.h
-          For PMIC7 ADC, the channel numbers are specified separately per PMIC
-          in the PMIC-specific files in include/dt-bindings/iio/.
-
-      label:
-        description: |
-            ADC input of the platform as seen in the schematics.
-            For thermistor inputs connected to generic AMUX or GPIO inputs
-            these can vary across platform for the same pins. Hence select
-            the platform schematics name for this channel.
-
-      qcom,decimation:
-        $ref: /schemas/types.yaml#/definitions/uint32
-        description: |
-            This parameter is used to decrease ADC sampling rate.
-            Quicker measurements can be made by reducing decimation ratio.
-
-      qcom,pre-scaling:
-        description: |
-            Used for scaling the channel input signal before the signal is
-            fed to VADC. The configuration for this node is to know the
-            pre-determined ratio and use it for post scaling. It is a pair of
-            integers, denoting the numerator and denominator of the fraction by which
-            input signal is multiplied. For example, <1 3> indicates the signal is scaled
-            down to 1/3 of its value before ADC measurement.
-            If property is not found default value depending on chip will be used.
-        $ref: /schemas/types.yaml#/definitions/uint32-array
-        oneOf:
-          - items:
-              - const: 1
-              - enum: [ 1, 3, 4, 6, 20, 8, 10, 16 ]
-          - items:
-              - const: 10
-              - const: 81
-
-      qcom,ratiometric:
-        description: |
-            Channel calibration type.
-            - For compatible property "qcom,spmi-vadc", if this property is
-              specified VADC will use the VDD reference (1.8V) and GND for
-              channel calibration. If property is not found, channel will be
-              calibrated with 0.625V and 1.25V reference channels, also
-              known as absolute calibration.
-            - For compatible property "qcom,spmi-adc5", "qcom,spmi-adc7" and
-              "qcom,spmi-adc-rev2", if this property is specified VADC will use
-              the VDD reference (1.875V) and GND for channel calibration. If
-              property is not found, channel will be calibrated with 0V and 1.25V
-              reference channels, also known as absolute calibration.
-        type: boolean
-
-      qcom,hw-settle-time:
-        $ref: /schemas/types.yaml#/definitions/uint32
-        description: |
-            Time between AMUX getting configured and the ADC starting
-            conversion. The 'hw_settle_time' is an index used from valid values
-            and programmed in hardware to achieve the hardware settling delay.
-
-      qcom,avg-samples:
-        $ref: /schemas/types.yaml#/definitions/uint32
-        description: |
-            Number of samples to be used for measurement.
-            Averaging provides the option to obtain a single measurement
-            from the ADC that is an average of multiple samples. The value
-            selected is 2^(value).
-
-    required:
-      - reg
+    $ref: /schemas/iio/adc/qcom,spmi-vadc-common.yaml
 
 allOf:
   - if:
diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
new file mode 100644
index 0000000..065637c
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
@@ -0,0 +1,101 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/amplifiers/adi,ad8366.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: AD8366 and similar Gain Amplifiers and Digital Attenuators
+
+maintainers:
+  - Michael Hennerich <michael.hennerich@analog.com>
+  - Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+description:
+  Digital Variable Gain Amplifiers (VGAs) and Digital Attenuators with
+  SPI interface.
+
+properties:
+  compatible:
+    enum:
+      - adi,ad8366
+      - adi,ada4961
+      - adi,adl5240
+      - adi,adrf5702
+      - adi,adrf5703
+      - adi,adrf5720
+      - adi,adrf5730
+      - adi,adrf5731
+      - adi,hmc271a
+      - adi,hmc792a
+      - adi,hmc1018a
+      - adi,hmc1019a
+      - adi,hmc1119
+
+  reg:
+    maxItems: 1
+
+  vcc-supply:
+    description: Regulator that provides power to the device.
+
+  reset-gpios:
+    maxItems: 1
+
+  enable-gpios:
+    maxItems: 1
+    description: Power-up or Serial Mode Enable GPIO.
+
+required:
+  - compatible
+  - reg
+  - vcc-supply
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              const: adi,hmc271a
+    then:
+      properties:
+        reset-gpios: false
+  - if:
+      not:
+        properties:
+          compatible:
+            contains:
+              anyOf:
+                - const: adi,ad8366
+                - const: adi,ada4961
+                - const: adi,adrf5702
+                - const: adi,adrf5703
+                - const: adi,adrf5720
+                - const: adi,adrf5730
+                - const: adi,adrf5731
+                - const: adi,hmc792a
+                - const: adi,hmc1018a
+                - const: adi,hmc1019a
+                - const: adi,hmc1119
+    then:
+      properties:
+        enable-gpios: false
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    spi {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      amplifier@0 {
+        compatible = "adi,ad8366";
+        reg = <0>;
+        spi-max-frequency = <1000000>;
+        vcc-supply = <&vcc_3v3>;
+        enable-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
+      };
+    };
+...
diff --git a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml
index 733edc7..50a9cbb 100644
--- a/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml
+++ b/Documentation/devicetree/bindings/iio/dac/lltc,ltc2632.yaml
@@ -4,36 +4,49 @@
 $id: http://devicetree.org/schemas/iio/dac/lltc,ltc2632.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Linear Technology LTC263x 12-/10-/8-Bit Rail-to-Rail DAC
+title: Linear Technology LTC263x and LTC2654 Rail-to-Rail DAC
 
 maintainers:
   - Michael Hennerich <michael.hennerich@analog.com>
 
 description: |
-  Bindings for the Linear Technology LTC2632/2634/2636 DAC
-  Datasheet can be found here: https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf
+  Bindings for the Linear Technology LTC2632/2634/2636/2654 DAC
+  Datasheet can be found here:
+    https://www.analog.com/media/en/technical-documentation/data-sheets/LTC263[246].pdf
+    https://www.analog.com/media/en/technical-documentation/data-sheets/2654f.pdf
 
 properties:
   compatible:
-    enum:
-      - lltc,ltc2632-l12
-      - lltc,ltc2632-l10
-      - lltc,ltc2632-l8
-      - lltc,ltc2632-h12
-      - lltc,ltc2632-h10
-      - lltc,ltc2632-h8
-      - lltc,ltc2634-l12
-      - lltc,ltc2634-l10
-      - lltc,ltc2634-l8
-      - lltc,ltc2634-h12
-      - lltc,ltc2634-h10
-      - lltc,ltc2634-h8
-      - lltc,ltc2636-l12
-      - lltc,ltc2636-l10
-      - lltc,ltc2636-l8
-      - lltc,ltc2636-h12
-      - lltc,ltc2636-h10
-      - lltc,ltc2636-h8
+    oneOf:
+      - enum:
+          - lltc,ltc2632-l12
+          - lltc,ltc2632-l10
+          - lltc,ltc2632-l8
+          - lltc,ltc2632-h12
+          - lltc,ltc2632-h10
+          - lltc,ltc2632-h8
+          - lltc,ltc2634-l12
+          - lltc,ltc2634-l10
+          - lltc,ltc2634-l8
+          - lltc,ltc2634-h12
+          - lltc,ltc2634-h10
+          - lltc,ltc2634-h8
+          - lltc,ltc2636-l12
+          - lltc,ltc2636-l10
+          - lltc,ltc2636-l8
+          - lltc,ltc2636-h12
+          - lltc,ltc2636-h10
+          - lltc,ltc2636-h8
+          - lltc,ltc2654-l16
+          - lltc,ltc2654-h16
+      - items:
+          - enum:
+              - lltc,ltc2654-l12
+          - const: lltc,ltc2634-l12
+      - items:
+          - enum:
+              - lltc,ltc2654-h12
+          - const: lltc,ltc2634-h12
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/dac/maxim,ds4424.yaml b/Documentation/devicetree/bindings/iio/dac/maxim,ds4424.yaml
index 264fa7c..4323df2 100644
--- a/Documentation/devicetree/bindings/iio/dac/maxim,ds4424.yaml
+++ b/Documentation/devicetree/bindings/iio/dac/maxim,ds4424.yaml
@@ -4,18 +4,21 @@
 $id: http://devicetree.org/schemas/iio/dac/maxim,ds4424.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Maxim Integrated DS4422/DS4424 7-bit Sink/Source Current DAC
+title: Maxim Integrated DS4402/DS4404 and DS4422/DS4424 Current DACs
 
 maintainers:
   - Ismail Kose <ihkose@gmail.com>
 
 description: |
-  Datasheet publicly available at:
+  Datasheets publicly available at:
+  https://datasheets.maximintegrated.com/en/ds/DS4402-DS4404.pdf
   https://datasheets.maximintegrated.com/en/ds/DS4422-DS4424.pdf
 
 properties:
   compatible:
     enum:
+      - maxim,ds4402
+      - maxim,ds4404
       - maxim,ds4422
       - maxim,ds4424
 
@@ -24,9 +27,43 @@
 
   vcc-supply: true
 
+  maxim,rfs-ohms:
+    description: |
+      Array of resistance values in Ohms for the external Rfs resistors
+      connected to the FS pins. These values determine the full-scale
+      output current. The actual resistance depends on the chip variant
+      and specific hardware design requirements.
+    minItems: 2
+    maxItems: 4
+
 required:
   - compatible
   - reg
+  - maxim,rfs-ohms
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - maxim,ds4402
+              - maxim,ds4422
+    then:
+      properties:
+        maxim,rfs-ohms:
+          maxItems: 2
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - maxim,ds4404
+              - maxim,ds4424
+    then:
+      properties:
+        maxim,rfs-ohms:
+          minItems: 4
 
 additionalProperties: false
 
@@ -40,6 +77,7 @@
             compatible = "maxim,ds4424";
             reg = <0x10>; /* When A0, A1 pins are ground */
             vcc-supply = <&vcc_3v3>;
+            maxim,rfs-ohms = <40000>, <40000>, <40000>, <40000>;
         };
     };
 ...
diff --git a/Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
index 20dd137..624c640 100644
--- a/Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
+++ b/Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml
@@ -9,7 +9,7 @@
 description:
   The DAC7612 is a dual, 12-bit digital-to-analog converter (DAC) with
   guaranteed 12-bit monotonicity performance over the industrial temperature
-  range. Is is programmable through an SPI interface.
+  range. It is programmable through an SPI interface.
 
 maintainers:
   - Ricardo Ribalda Delgado <ricardo@ribalda.com>
diff --git a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml
index 3c6fe74..fcbd4b4 100644
--- a/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml
+++ b/Documentation/devicetree/bindings/iio/gyroscope/bosch,bmg160.yaml
@@ -11,10 +11,14 @@
 
 properties:
   compatible:
-    enum:
-      - bosch,bmg160
-      - bosch,bmi055_gyro
-      - bosch,bmi088_gyro
+    oneOf:
+      - enum:
+          - bosch,bmg160
+          - bosch,bmi055_gyro
+          - bosch,bmi088_gyro
+      - items:
+          - const: bosch,bmx055-gyro
+          - const: bosch,bmg160
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml
index 4d1a225..516afef 100644
--- a/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml
+++ b/Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml
@@ -18,16 +18,32 @@
 
 properties:
   compatible:
-    enum:
-      - vishay,vcnl4000
-      - vishay,vcnl4010
-      - vishay,vcnl4020
-      - vishay,vcnl4040
-      - vishay,vcnl4200
+    oneOf:
+      - enum:
+          - capella,cm36672p
+          - vishay,vcnl4000
+          - vishay,vcnl4010
+          - vishay,vcnl4020
+          - vishay,vcnl4040
+          - vishay,vcnl4200
+      - items:
+          - const: capella,cm36686
+          - const: vishay,vcnl4040
 
   interrupts:
     maxItems: 1
 
+  vdd-supply:
+    description: Regulator providing power to the "VDD" pin.
+
+  vio-supply:
+    description: Regulator providing power for pull-up of the I/O lines.
+      Does not connect to the sensor directly, but is needed for the
+      correct operation of the I2C and interrupt lines.
+
+  vled-supply:
+    description: Regulator providing power to the IR anode pin.
+
   reg:
     maxItems: 1
 
@@ -49,6 +65,9 @@
             compatible = "vishay,vcnl4200";
             reg = <0x51>;
             proximity-near-level = <220>;
+            vdd-supply = <&reg_vdd>;
+            vio-supply = <&reg_vio>;
+            vled-supply = <&reg_vled>;
         };
     };
 ...
diff --git a/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml b/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml
index a3838ab..c1a6892 100644
--- a/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml
+++ b/Documentation/devicetree/bindings/iio/magnetometer/bosch,bmc150_magn.yaml
@@ -21,11 +21,15 @@
     description:
       Note the bmm150_magn is a deprecated compatible as this part contains only
       a magnetometer.
-    enum:
-      - bosch,bmc150_magn
-      - bosch,bmc156_magn
-      - bosch,bmm150
-      - bosch,bmm150_magn
+    oneOf:
+      - enum:
+          - bosch,bmc150_magn
+          - bosch,bmc156_magn
+          - bosch,bmm150
+          - bosch,bmm150_magn
+      - items:
+          - const: bosch,bmx055-magn
+          - const: bosch,bmc150_magn
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml b/Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
index 322befc..f7f8be1 100644
--- a/Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
+++ b/Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
@@ -4,14 +4,17 @@
 $id: http://devicetree.org/schemas/iio/proximity/st,vl53l0x.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: ST VL53L0X ToF ranging sensor
+title: ST VL53L0X/VL53L1X ToF ranging sensor
 
 maintainers:
   - Song Qiang <songqiang1304521@gmail.com>
+  - Siratul Islam <email@sirat.me>
 
 properties:
   compatible:
-    const: st,vl53l0x
+    enum:
+      - st,vl53l0x
+      - st,vl53l1x
 
   reg:
     maxItems: 1
@@ -21,6 +24,8 @@
 
   reset-gpios:
     maxItems: 1
+    description:
+      Phandle to the XSHUT GPIO. Used for hardware reset.
 
   vdd-supply: true
 
@@ -28,6 +33,16 @@
   - compatible
   - reg
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: st,vl53l1x
+    then:
+      required:
+        - vdd-supply
+
 additionalProperties: false
 
 examples:
@@ -38,8 +53,9 @@
         #size-cells = <0>;
 
         proximity@29 {
-            compatible = "st,vl53l0x";
+            compatible = "st,vl53l1x";
             reg = <0x29>;
+            vdd-supply = <&reg_3v3>;
             interrupt-parent = <&gpio>;
             interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
         };
diff --git a/Documentation/devicetree/bindings/iio/proximity/tyhx,hx9023s.yaml b/Documentation/devicetree/bindings/iio/proximity/tyhx,hx9023s.yaml
index 64ce8bc..cc5b528 100644
--- a/Documentation/devicetree/bindings/iio/proximity/tyhx,hx9023s.yaml
+++ b/Documentation/devicetree/bindings/iio/proximity/tyhx,hx9023s.yaml
@@ -28,6 +28,9 @@
 
   vdd-supply: true
 
+  firmware-name:
+    maxItems: 1
+
   "#address-cells":
     const: 1
 
@@ -65,6 +68,7 @@
         interrupt-parent = <&pio>;
         interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
         vdd-supply = <&pp1800_prox>;
+        firmware-name = "hx9023s.bin";
 
         #address-cells = <1>;
         #size-cells = <0>;
diff --git a/Documentation/devicetree/bindings/input/awinic,aw86927.yaml b/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
index b725291..bd74b81 100644
--- a/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
+++ b/Documentation/devicetree/bindings/input/awinic,aw86927.yaml
@@ -11,7 +11,12 @@
 
 properties:
   compatible:
-    const: awinic,aw86927
+    oneOf:
+      - const: awinic,aw86927
+      - items:
+          - enum:
+              - awinic,aw86938
+          - const: awinic,aw86927
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml b/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
index a0d2460..25b8b29 100644
--- a/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/cirrus,ep9307-keypad.yaml
@@ -10,6 +10,7 @@
   - Alexander Sverdlin <alexander.sverdlin@gmail.com>
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 description:
@@ -37,10 +38,8 @@
   clocks:
     maxItems: 1
 
-  debounce-delay-ms:
-    description: |
-          Time in microseconds that key must be pressed or
-          released for state change interrupt to trigger.
+  # Time for state change interrupt to trigger
+  debounce-delay-ms: true
 
   cirrus,prescale:
     description: row/column counter pre-scaler load value
diff --git a/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
new file mode 100644
index 0000000..c085de6
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
@@ -0,0 +1,108 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+
+$id: http://devicetree.org/schemas/input/gpio-charlieplex-keypad.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GPIO charlieplex keypad
+
+maintainers:
+  - Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+description: |
+  The charlieplex keypad supports N^2)-N different key combinations (where N is
+  the number of I/O lines). Key presses and releases are detected by configuring
+  only one line as output at a time, and reading other line states. This process
+  is repeated for each line. Diodes are required to ensure current flows in only
+  one direction between any pair of pins, as well as pull-up or pull-down
+  resistors on all I/O lines.
+  This mechanism doesn't allow to detect simultaneous key presses.
+
+  Wiring example for 3 lines keyboard with 6 switches and 3 diodes (pull-up/down
+  resistors not shown but needed on L0, L1 and L2):
+
+  L0  --+---------------------+----------------------+
+        |                     |                      |
+  L1  -------+-----------+---------------------+     |
+        |    |           |    |                |     |
+  L2  -------------+----------------+-----+    |     |
+        |    |     |     |    |     |     |    |     |
+        |    |     |     |    |     |     |    |     |
+        |  S1 \  S2 \    |  S3 \  S4 \    |  S5 \  S6 \
+        |    |     |     |    |     |     |    |     |
+        |    +--+--+     |    +--+--+     |    +--+--+
+        |       |        |       |        |       |
+        |    D1 v        |    D2 v        |    D3 v
+        |       - (k)    |       - (k)    |       - (k)
+        |       |        |       |        |       |
+        +-------+        +-------+        +-------+
+
+  L: GPIO line
+  S: switch
+  D: diode (k indicates cathode)
+
+allOf:
+  - $ref: input.yaml#
+  - $ref: /schemas/input/matrix-keymap.yaml#
+
+properties:
+  compatible:
+    const: gpio-charlieplex-keypad
+
+  autorepeat: true
+
+  debounce-delay-ms:
+    default: 5
+
+  line-gpios:
+    description:
+      List of GPIOs used as lines. The gpio specifier for this property
+      depends on the gpio controller to which these lines are connected.
+
+  linux,keymap: true
+
+  poll-interval: true
+
+  settling-time-us: true
+
+  wakeup-source: true
+
+required:
+  - compatible
+  - line-gpios
+  - linux,keymap
+  - poll-interval
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/input/input.h>
+
+    keyboard {
+        compatible = "gpio-charlieplex-keypad";
+        debounce-delay-ms = <20>;
+        poll-interval = <5>;
+        settling-time-us = <2>;
+
+        line-gpios = <&gpio2 25 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)
+                      &gpio2 26 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)
+                      &gpio2 27 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>;
+
+        /* MATRIX_KEY(output, input, key-code) */
+        linux,keymap = <
+            /*
+             * According to wiring diagram above, if L1 is configured as
+             * output and HIGH, and we detect a HIGH level on input L0,
+             * then it means S1 is pressed: MATRIX_KEY(L1, L0, KEY...)
+             */
+            MATRIX_KEY(1, 0, KEY_F1) /* S1 */
+            MATRIX_KEY(2, 0, KEY_F2) /* S2 */
+            MATRIX_KEY(0, 1, KEY_F3) /* S3 */
+            MATRIX_KEY(2, 1, KEY_F4) /* S4 */
+            MATRIX_KEY(1, 2, KEY_F5) /* S5 */
+            MATRIX_KEY(0, 2, KEY_F6) /* S6 */
+        >;
+    };
diff --git a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
index ebfff9e..69df24a 100644
--- a/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/gpio-matrix-keypad.yaml
@@ -18,6 +18,7 @@
   report the event using GPIO interrupts to the cpu.
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 properties:
@@ -46,9 +47,7 @@
       Force GPIO polarity to active low.
       In the absence of this property GPIOs are treated as active high.
 
-  debounce-delay-ms:
-    description: Debounce interval in milliseconds.
-    default: 0
+  debounce-delay-ms: true
 
   col-scan-delay-us:
     description:
diff --git a/Documentation/devicetree/bindings/input/input.yaml b/Documentation/devicetree/bindings/input/input.yaml
index 94f7942..64d1c46 100644
--- a/Documentation/devicetree/bindings/input/input.yaml
+++ b/Documentation/devicetree/bindings/input/input.yaml
@@ -14,6 +14,14 @@
     description: Enable autorepeat when key is pressed and held down.
     type: boolean
 
+  debounce-delay-ms:
+    description:
+      Debounce delay in milliseconds. This is the time during which the key
+      press or release signal must remain stable before it is considered valid.
+    minimum: 0
+    maximum: 999
+    default: 0
+
   linux,keycodes:
     description:
       Specifies an array of numeric keycode values to be used for reporting
@@ -58,6 +66,14 @@
       reset automatically. Device with key pressed reset feature can specify
       this property.
 
+  settling-time-us:
+    description:
+      Delay, in microseconds, when activating an output line/col/row before
+      we can reliably read other input lines that maybe affected by this
+      output. This can be the case for an output with a RC circuit that affects
+      ramp-up/down times.
+    default: 0
+
 dependencies:
   linux,input-type: [ "linux,code" ]
 
diff --git a/Documentation/devicetree/bindings/input/matrix-keymap.yaml b/Documentation/devicetree/bindings/input/matrix-keymap.yaml
index a715c2a..ce910e4 100644
--- a/Documentation/devicetree/bindings/input/matrix-keymap.yaml
+++ b/Documentation/devicetree/bindings/input/matrix-keymap.yaml
@@ -4,13 +4,13 @@
 $id: http://devicetree.org/schemas/input/matrix-keymap.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Common Key Matrices on Matrix-connected Key Boards
+title: Common Key Matrices on Matrix-connected Keyboards
 
 maintainers:
   - Olof Johansson <olof@lixom.net>
 
 description: |
-  A simple common binding for matrix-connected key boards. Currently targeted at
+  A simple common binding for matrix-connected keyboards. Currently targeted at
   defining the keys in the scope of linux key codes since that is a stable and
   standardized interface at this time.
 
diff --git a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
index e365413..914dd32 100644
--- a/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
+++ b/Documentation/devicetree/bindings/input/mediatek,mt6779-keypad.yaml
@@ -10,6 +10,7 @@
   - Mattijs Korpershoek <mkorpershoek@kernel.org>
 
 allOf:
+  - $ref: input.yaml#
   - $ref: /schemas/input/matrix-keymap.yaml#
 
 description: |
diff --git a/Documentation/devicetree/bindings/input/parade,tc3408.yaml b/Documentation/devicetree/bindings/input/parade,tc3408.yaml
new file mode 100644
index 0000000..30ffefb
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/parade,tc3408.yaml
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/parade,tc3408.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Parade TC3408 touchscreen controller
+
+maintainers:
+  - Langyan Ye <yelangyan@huaqin.corp-partner.google.com>
+
+description: |
+  Parade TC3408 is a touchscreen controller supporting the I2C-HID protocol.
+  It requires a reset GPIO and two power supplies (3.3V and 1.8V).
+
+allOf:
+  - $ref: /schemas/input/touchscreen/touchscreen.yaml#
+
+properties:
+  compatible:
+    const: parade,tc3408
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  vcc33-supply:
+    description: The 3.3V supply to the touchscreen.
+
+  vccio-supply:
+    description: The 1.8V supply to the touchscreen.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - reset-gpios
+  - vcc33-supply
+  - vccio-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+
+      touchscreen: touchscreen@24 {
+        compatible = "parade,tc3408";
+        reg = <0x24>;
+
+        interrupt-parent = <&pio>;
+        interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
+
+        reset-gpios = <&pio 126 GPIO_ACTIVE_LOW>;
+        vcc33-supply = <&pp3300_tchscr_x>;
+        vccio-supply = <&pp1800_tchscr_report_disable>;
+      };
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch.yaml b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch.yaml
index 402ca6b..44158e8 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/apple,z2-multitouch.yaml
@@ -7,7 +7,7 @@
 title: Apple touchscreens attached using the Z2 protocol
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description: A series of touschscreen controllers used in Apple products
 
diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
index 6f90522..68b2f16 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
@@ -33,19 +33,23 @@
 
 properties:
   compatible:
-    enum:
-      - edt,edt-ft5206
-      - edt,edt-ft5306
-      - edt,edt-ft5406
-      - edt,edt-ft5506
-      - evervision,ev-ft5726
-      - focaltech,ft3518
-      - focaltech,ft5426
-      - focaltech,ft5452
-      - focaltech,ft6236
-      - focaltech,ft8201
-      - focaltech,ft8716
-      - focaltech,ft8719
+    oneOf:
+      - enum:
+          - edt,edt-ft5206
+          - edt,edt-ft5306
+          - edt,edt-ft5406
+          - edt,edt-ft5506
+          - evervision,ev-ft5726
+          - focaltech,ft3518
+          - focaltech,ft5426
+          - focaltech,ft5452
+          - focaltech,ft6236
+          - focaltech,ft8201
+          - focaltech,ft8716
+          - focaltech,ft8719
+      - items:
+          - const: focaltech,ft3519
+          - const: focaltech,ft3518
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml b/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml
index 978afaa..fe1fa21 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml
@@ -32,6 +32,9 @@
     description: A phandle to the reset GPIO
     maxItems: 1
 
+  wakeup-source:
+    type: boolean
+
 required:
   - compatible
   - reg
@@ -51,6 +54,7 @@
                     reg = <0x55>;
                     interrupts = <2 0>;
                     gpios = <&gpio1 166 0>;
+                    wakeup-source;
 
                     touch-overlay {
                             segment-0 {
diff --git a/Documentation/devicetree/bindings/input/touchscreen/technologic,ts4800-ts.yaml b/Documentation/devicetree/bindings/input/touchscreen/technologic,ts4800-ts.yaml
new file mode 100644
index 0000000..c033774
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/technologic,ts4800-ts.yaml
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/technologic,ts4800-ts.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TS-4800 Touchscreen
+
+maintainers:
+  - Eduard Bostina <egbostina@gmail.com>
+
+properties:
+  compatible:
+    const: technologic,ts4800-ts
+
+  reg:
+    maxItems: 1
+
+  syscon:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    items:
+      - items:
+          - description: Phandle to the FPGA's syscon
+          - description: Offset to the touchscreen register
+          - description: Offset to the touchscreen enable bit
+    description: Phandle / integers array that points to the syscon node which
+      describes the FPGA's syscon registers.
+
+required:
+  - compatible
+  - reg
+  - syscon
+
+additionalProperties: false
+
+examples:
+  - |
+    touchscreen@1000 {
+        compatible = "technologic,ts4800-ts";
+        reg = <0x1000 0x100>;
+        syscon = <&fpga_syscon 0x20 3>;
+    };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml
index 6441d21..6316a8d 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml
@@ -53,14 +53,14 @@
 
   wakeup-source: true
 
-allOf:
-  - $ref: touchscreen.yaml
-
 required:
   - compatible
   - reg
   - interrupts
 
+allOf:
+  - $ref: touchscreen.yaml
+
 unevaluatedProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt b/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt
deleted file mode 100644
index 4c1c092..0000000
--- a/Documentation/devicetree/bindings/input/touchscreen/ts4800-ts.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-* TS-4800 Touchscreen bindings
-
-Required properties:
-- compatible: must be "technologic,ts4800-ts"
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- syscon: phandle / integers array that points to the syscon node which
-          describes the FPGA's syscon registers.
-          - phandle to FPGA's syscon
-          - offset to the touchscreen register
-          - offset to the touchscreen enable bit
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml
index d55a7bc..f69b2fa 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,glymur-rpmh.yaml
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/interconnect/qcom,glymur-rpmh.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: Qualcomm RPMh Network-On-Chip Interconnect on GLYMUR
+title: Qualcomm RPMh Network-On-Chip Interconnect on Glymur and Mahua SoCs
 
 maintainers:
   - Raviteja Laggyshetty <raviteja.laggyshetty@oss.qualcomm.com>
@@ -21,28 +21,98 @@
 
 properties:
   compatible:
-    enum:
-      - qcom,glymur-aggre1-noc
-      - qcom,glymur-aggre2-noc
-      - qcom,glymur-aggre3-noc
-      - qcom,glymur-aggre4-noc
-      - qcom,glymur-clk-virt
-      - qcom,glymur-cnoc-cfg
-      - qcom,glymur-cnoc-main
-      - qcom,glymur-hscnoc
-      - qcom,glymur-lpass-ag-noc
-      - qcom,glymur-lpass-lpiaon-noc
-      - qcom,glymur-lpass-lpicx-noc
-      - qcom,glymur-mc-virt
-      - qcom,glymur-mmss-noc
-      - qcom,glymur-nsinoc
-      - qcom,glymur-nsp-noc
-      - qcom,glymur-oobm-ss-noc
-      - qcom,glymur-pcie-east-anoc
-      - qcom,glymur-pcie-east-slv-noc
-      - qcom,glymur-pcie-west-anoc
-      - qcom,glymur-pcie-west-slv-noc
-      - qcom,glymur-system-noc
+    oneOf:
+      - items:
+          - enum:
+              - qcom,mahua-aggre1-noc
+          - const: qcom,glymur-aggre1-noc
+      - items:
+          - enum:
+              - qcom,mahua-aggre2-noc
+          - const: qcom,glymur-aggre2-noc
+      - items:
+          - enum:
+              - qcom,mahua-aggre3-noc
+          - const: qcom,glymur-aggre3-noc
+      - items:
+          - enum:
+              - qcom,mahua-aggre4-noc
+          - const: qcom,glymur-aggre4-noc
+      - items:
+          - enum:
+              - qcom,mahua-clk-virt
+          - const: qcom,glymur-clk-virt
+      - items:
+          - enum:
+              - qcom,mahua-cnoc-main
+          - const: qcom,glymur-cnoc-main
+      - items:
+          - enum:
+              - qcom,mahua-lpass-ag-noc
+          - const: qcom,glymur-lpass-ag-noc
+      - items:
+          - enum:
+              - qcom,mahua-lpass-lpiaon-noc
+          - const: qcom,glymur-lpass-lpiaon-noc
+      - items:
+          - enum:
+              - qcom,mahua-lpass-lpicx-noc
+          - const: qcom,glymur-lpass-lpicx-noc
+      - items:
+          - enum:
+              - qcom,mahua-mmss-noc
+          - const: qcom,glymur-mmss-noc
+      - items:
+          - enum:
+              - qcom,mahua-nsinoc
+          - const: qcom,glymur-nsinoc
+      - items:
+          - enum:
+              - qcom,mahua-nsp-noc
+          - const: qcom,glymur-nsp-noc
+      - items:
+          - enum:
+              - qcom,mahua-oobm-ss-noc
+          - const: qcom,glymur-oobm-ss-noc
+      - items:
+          - enum:
+              - qcom,mahua-pcie-east-anoc
+          - const: qcom,glymur-pcie-east-anoc
+      - items:
+          - enum:
+              - qcom,mahua-pcie-east-slv-noc
+          - const: qcom,glymur-pcie-east-slv-noc
+      - items:
+          - enum:
+              - qcom,mahua-system-noc
+          - const: qcom,glymur-system-noc
+      - enum:
+          - qcom,glymur-aggre1-noc
+          - qcom,glymur-aggre2-noc
+          - qcom,glymur-aggre3-noc
+          - qcom,glymur-aggre4-noc
+          - qcom,glymur-clk-virt
+          - qcom,glymur-cnoc-cfg
+          - qcom,glymur-cnoc-main
+          - qcom,glymur-hscnoc
+          - qcom,glymur-lpass-ag-noc
+          - qcom,glymur-lpass-lpiaon-noc
+          - qcom,glymur-lpass-lpicx-noc
+          - qcom,glymur-mc-virt
+          - qcom,glymur-mmss-noc
+          - qcom,glymur-nsinoc
+          - qcom,glymur-nsp-noc
+          - qcom,glymur-oobm-ss-noc
+          - qcom,glymur-pcie-east-anoc
+          - qcom,glymur-pcie-east-slv-noc
+          - qcom,glymur-pcie-west-anoc
+          - qcom,glymur-pcie-west-slv-noc
+          - qcom,glymur-system-noc
+          - qcom,mahua-cnoc-cfg
+          - qcom,mahua-hscnoc
+          - qcom,mahua-mc-virt
+          - qcom,mahua-pcie-west-anoc
+          - qcom,mahua-pcie-west-slv-noc
 
   reg:
     maxItems: 1
@@ -63,6 +133,7 @@
             enum:
               - qcom,glymur-clk-virt
               - qcom,glymur-mc-virt
+              - qcom,mahua-mc-virt
     then:
       properties:
         reg: false
@@ -90,6 +161,20 @@
         compatible:
           contains:
             enum:
+              - qcom,mahua-pcie-west-anoc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: aggre PCIE_3B WEST AXI clock
+            - description: aggre PCIE_4 WEST AXI clock
+            - description: aggre PCIE_6 WEST AXI clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
               - qcom,glymur-pcie-east-anoc
     then:
       properties:
@@ -131,10 +216,11 @@
         compatible:
           contains:
             enum:
-              - qcom,glymur-pcie-west-anoc
-              - qcom,glymur-pcie-east-anoc
               - qcom,glymur-aggre2-noc
               - qcom,glymur-aggre4-noc
+              - qcom,glymur-pcie-east-anoc
+              - qcom,glymur-pcie-west-anoc
+              - qcom,mahua-pcie-west-anoc
     then:
       required:
         - clocks
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
index 95ce25c..b35f6dd 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8974.yaml
@@ -26,27 +26,34 @@
       - qcom,msm8974-pnoc
       - qcom,msm8974-snoc
 
-  '#interconnect-cells':
-    const: 1
-
   clock-names:
     items:
       - const: bus
-      - const: bus_a
 
   clocks:
     items:
       - description: Bus Clock
-      - description: Bus A Clock
 
 required:
   - compatible
   - reg
-  - '#interconnect-cells'
-  - clock-names
-  - clocks
 
-additionalProperties: false
+unevaluatedProperties: false
+
+allOf:
+  - $ref: qcom,rpm-common.yaml#
+  - if:
+      properties:
+        compatible:
+          const: qcom,msm8974-mmssnoc
+    then:
+      required:
+        - clocks
+        - clock-names
+    else:
+      properties:
+        clocks: false
+        clock-names: false
 
 examples:
   - |
@@ -56,7 +63,4 @@
         reg = <0xfc380000 0x6a000>;
         compatible = "qcom,msm8974-bimc";
         #interconnect-cells = <1>;
-        clock-names = "bus", "bus_a";
-        clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
-                 <&rpmcc RPM_SMD_BIMC_A_CLK>;
     };
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml
index 6182599..41b9f75 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,osm-l3.yaml
@@ -35,6 +35,7 @@
               - qcom,sm6375-cpucp-l3
               - qcom,sm8250-epss-l3
               - qcom,sm8350-epss-l3
+              - qcom,sm8550-epss-l3
               - qcom,sm8650-epss-l3
           - const: qcom,epss-l3
       - items:
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml
index e064048..a9cd49b 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml
@@ -34,6 +34,13 @@
   reg:
     maxItems: 1
 
+  clocks:
+    items:
+      - description: aggre UFS PHY AXI clock
+      - description: aggre USB2 SEC AXI clock
+      - description: aggre USB3 PRIM AXI clock
+      - description: RPMH CC IPA clock
+
 required:
   - compatible
 
@@ -53,6 +60,22 @@
       required:
         - reg
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs615-camnoc-virt
+              - qcom,qcs615-config-noc
+              - qcom,qcs615-dc-noc
+              - qcom,qcs615-gem-noc
+              - qcom,qcs615-mc-virt
+              - qcom,qcs615-mmss-noc
+              - qcom,qcs615-system-noc
+    then:
+      properties:
+        clocks: false
+
 unevaluatedProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml
index e9f528d..88fe172 100644
--- a/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml
+++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs8300-rpmh.yaml
@@ -35,6 +35,10 @@
   reg:
     maxItems: 1
 
+  clocks:
+    minItems: 1
+    maxItems: 4
+
 required:
   - compatible
 
@@ -54,6 +58,64 @@
       required:
         - reg
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs8300-aggre1-noc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: aggre UFS PHY AXI clock
+            - description: aggre QUP PRIM AXI clock
+            - description: aggre USB2 PRIM AXI clock
+            - description: aggre USB3 PRIM AXI clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs8300-aggre2-noc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: RPMH CC IPA clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs8300-gem-noc
+    then:
+      properties:
+        clocks:
+          items:
+            - description: GCC DDRSS GPU AXI clock
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,qcs8300-clk-virt
+              - qcom,qcs8300-config-noc
+              - qcom,qcs8300-dc-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
+    then:
+      properties:
+        clocks: false
+
 unevaluatedProperties: false
 
 examples:
@@ -63,6 +125,7 @@
         reg = <0x9100000 0xf7080>;
         #interconnect-cells = <2>;
         qcom,bcm-voters = <&apps_bcm_voter>;
+        clocks = <&gcc_ddrss_gpu_axi_clk>;
     };
 
     clk_virt: interconnect-0 {
diff --git a/Documentation/devicetree/bindings/leds/leds-lp5860.yaml b/Documentation/devicetree/bindings/leds/leds-lp5860.yaml
index 1ccba48..0e88c71 100644
--- a/Documentation/devicetree/bindings/leds/leds-lp5860.yaml
+++ b/Documentation/devicetree/bindings/leds/leds-lp5860.yaml
@@ -33,6 +33,11 @@
   '#size-cells':
     const: 0
 
+  enable-gpios:
+    maxItems: 1
+    description: |
+      GPIO attached to the chip's enable pin (VIO_EN).
+
 patternProperties:
   '^multi-led@[0-9a-f]+$':
     type: object
@@ -74,6 +79,7 @@
 
 examples:
   - |
+    #include <dt-bindings/gpio/gpio.h>
     #include <dt-bindings/leds/common.h>
 
     spi {
@@ -83,6 +89,7 @@
         led-controller@0 {
             compatible = "ti,lp5860";
             reg = <0x0>;
+            enable-gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
             #address-cells = <1>;
             #size-cells = <0>;
 
diff --git a/Documentation/devicetree/bindings/leds/sprd,sc2731-bltc.yaml b/Documentation/devicetree/bindings/leds/sprd,sc2731-bltc.yaml
index 97535d6..2ae5cc3 100644
--- a/Documentation/devicetree/bindings/leds/sprd,sc2731-bltc.yaml
+++ b/Documentation/devicetree/bindings/leds/sprd,sc2731-bltc.yaml
@@ -18,7 +18,12 @@
 
 properties:
   compatible:
-    const: sprd,sc2731-bltc
+    oneOf:
+      - items:
+          - enum:
+              - sprd,sc2730-bltc
+          - const: sprd,sc2731-bltc
+      - const: sprd,sc2731-bltc
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/mfd/fsl,imx25-tsadc.yaml b/Documentation/devicetree/bindings/mfd/fsl,imx25-tsadc.yaml
new file mode 100644
index 0000000..b5c6a2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/fsl,imx25-tsadc.yaml
@@ -0,0 +1,97 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/fsl,imx25-tsadc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale MX25 ADC/TSC MultiFunction Device (MFD)
+
+maintainers:
+  - Frank Li <Frank.Li@nxp.com>
+
+description:
+  This device combines two general purpose conversion queues one used for general
+  ADC and the other used for touchscreens.
+
+properties:
+  compatible:
+    const: fsl,imx25-tsadc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: ipg
+
+  interrupt-controller: true
+
+  '#interrupt-cells':
+    const: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  '^touchscreen@[0-9a-f]+$':
+    type: object
+    $ref: /schemas/input/touchscreen/fsl,imx25-tcq.yaml
+    unevaluatedProperties: false
+
+  '^adc@[0-9a-f]+$':
+    type: object
+    $ref: /schemas/iio/adc/fsl,imx25-gcq.yaml
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - '#interrupt-cells'
+  - '#address-cells'
+  - '#size-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    tscadc@50030000 {
+        compatible = "fsl,imx25-tsadc";
+        reg = <0x50030000 0xc>;
+        interrupts = <46>;
+        clocks = <&clks 119>;
+        clock-names = "ipg";
+        interrupt-controller;
+        #interrupt-cells = <1>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        touchscreen@50030400 {
+            compatible = "fsl,imx25-tcq";
+            reg = <0x50030400 0x60>;
+            interrupts = <0>;
+            fsl,wires = <4>;
+        };
+
+        adc@50030800 {
+            compatible = "fsl,imx25-gcq";
+            reg = <0x50030800 0x60>;
+            interrupts = <1>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
index cfa69f1..5cdb25b 100644
--- a/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
+++ b/Documentation/devicetree/bindings/mfd/fsl,mc13xxx.yaml
@@ -76,8 +76,6 @@
           debounce-delay-ms:
             enum: [0, 30, 150, 750]
             default: 30
-            description:
-              Sets the debouncing delay in milliseconds.
 
           active-low:
             description: Set active when pin is pulled low.
diff --git a/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt b/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
deleted file mode 100644
index b035052..0000000
--- a/Documentation/devicetree/bindings/mfd/fsl-imx25-tsadc.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Freescale MX25 ADC/TSC MultiFunction Device (MFD)
-
-This device combines two general purpose conversion queues one used for general
-ADC and the other used for touchscreens.
-
-Required properties:
- - compatible:			Should be "fsl,imx25-tsadc".
- - reg:				Start address and size of the memory area of
- 					the device
- - interrupts:			Interrupt for this device
-					(See: ../interrupt-controller/interrupts.txt)
- - clocks:			An 'ipg' clock (See: ../clock/clock-bindings.txt)
- - interrupt-controller:	This device is an interrupt controller. It
-   					controls the interrupts of both
-					conversion queues.
- - #interrupt-cells:		Should be '<1>'.
- - #address-cells:		Should be '<1>'.
- - #size-cells:			Should be '<1>'.
-
-This device includes two conversion queues which can be added as subnodes.
-The first queue is for the touchscreen, the second for general purpose ADC.
-
-Example:
-	tscadc: tscadc@50030000 {
-		compatible = "fsl,imx25-tsadc";
-		reg = <0x50030000 0xc>;
-		interrupts = <46>;
-		clocks = <&clks 119>;
-		clock-names = "ipg";
-		interrupt-controller;
-		#interrupt-cells = <1>;
-		#address-cells = <1>;
-		#size-cells = <1>;
-		ranges;
-
-		tsc: tcq@50030400 {
-			compatible = "fsl,imx25-tcq";
-			reg = <0x50030400 0x60>;
-			...
-		};
-
-		adc: gcq@50030800 {
-			compatible = "fsl,imx25-gcq";
-			reg = <0x50030800 0x60>;
-			...
-		};
-	};
diff --git a/Documentation/devicetree/bindings/mfd/max77620.txt b/Documentation/devicetree/bindings/mfd/max77620.txt
deleted file mode 100644
index 5a642a5..0000000
--- a/Documentation/devicetree/bindings/mfd/max77620.txt
+++ /dev/null
@@ -1,162 +0,0 @@
-MAX77620 Power management IC from Maxim Semiconductor.
-
-Required properties:
--------------------
-- compatible: Must be one of
-		"maxim,max77620"
-		"maxim,max20024"
-		"maxim,max77663"
-- reg: I2C device address.
-
-Optional properties:
--------------------
-- interrupts:		The interrupt on the parent the controller is
-			connected to.
-- interrupt-controller: Marks the device node as an interrupt controller.
-- #interrupt-cells:	is <2> and their usage is compliant to the 2 cells
-			variant of <../interrupt-controller/interrupts.txt>
-			IRQ numbers for different interrupt source of MAX77620
-			are defined at dt-bindings/mfd/max77620.h.
-
-- system-power-controller: Indicates that this PMIC is controlling the
-			   system power, see [1] for more details.
-
-[1] Documentation/devicetree/bindings/power/power-controller.txt
-
-Optional subnodes and their properties:
-=======================================
-
-Flexible power sequence configurations:
---------------------------------------
-The Flexible Power Sequencer (FPS) allows each regulator to power up under
-hardware or software control. Additionally, each regulator can power on
-independently or among a group of other regulators with an adjustable power-up
-and power-down delays (sequencing). GPIO1, GPIO2, and GPIO3 can be programmed
-to be part of a sequence allowing external regulators to be sequenced along
-with internal regulators. 32KHz clock can be programmed to be part of a
-sequence.
-
-The flexible sequencing structure consists of two hardware enable inputs
-(EN0, EN1), and 3 master sequencing timers called FPS0, FPS1 and FPS2.
-Each master sequencing timer is programmable through its configuration
-register to have a hardware enable source (EN1 or EN2) or a software enable
-source (SW). When enabled/disabled, the master sequencing timer generates
-eight sequencing events on different time periods called slots. The time
-period between each event is programmable within the configuration register.
-Each regulator, GPIO1, GPIO2, GPIO3, and 32KHz clock has a flexible power
-sequence slave register which allows its enable source to be specified as
-a flexible power sequencer timer or a software bit. When a FPS source of
-regulators, GPIOs and clocks specifies the enable source to be a flexible
-power sequencer, the power up and power down delays can be specified in
-the regulators, GPIOs and clocks flexible power sequencer configuration
-registers.
-
-When FPS event cleared (set to LOW), regulators, GPIOs and 32KHz
-clock are set into following state at the sequencing event that
-corresponds to its flexible sequencer configuration register.
-	Sleep state: 			In this state, regulators, GPIOs
-					and 32KHz clock get disabled at
-					the sequencing event.
-	Global Low Power Mode (GLPM):	In this state, regulators are set in
-					low power mode at the sequencing event.
-
-The configuration parameters of FPS is provided through sub-node "fps"
-and their child for FPS specific. The child node name for FPS are "fps0",
-"fps1", and "fps2" for FPS0, FPS1 and FPS2 respectively.
-
-The FPS configurations like FPS source, power up and power down slots for
-regulators, GPIOs and 32kHz clocks are provided in their respective
-configuration nodes which is explained in respective sub-system DT
-binding document.
-
-There is need for different FPS configuration parameters based on system
-state like when system state changed from active to suspend or active to
-power off (shutdown).
-
-Optional properties:
--------------------
--maxim,fps-event-source:		u32, FPS event source like external
-					hardware input to PMIC i.e. EN0, EN1 or
-					software (SW).
-					The macros are defined on
-						dt-bindings/mfd/max77620.h
-					for different control source.
-					- MAX77620_FPS_EVENT_SRC_EN0
-						for hardware input pin EN0.
-					- MAX77620_FPS_EVENT_SRC_EN1
-						for hardware input pin EN1.
-					- MAX77620_FPS_EVENT_SRC_SW
-						for software control.
-
--maxim,shutdown-fps-time-period-us:	u32, FPS time period in microseconds
-					when system enters in to shutdown
-					state.
-
--maxim,suspend-fps-time-period-us:	u32, FPS time period in microseconds
-					when system enters in to suspend state.
-
--maxim,device-state-on-disabled-event:	u32, describe the PMIC state when FPS
-					event cleared (set to LOW) whether it
-					should go to sleep state or low-power
-					state. Following are valid values:
-					- MAX77620_FPS_INACTIVE_STATE_SLEEP
-						to set the PMIC state to sleep.
-					- MAX77620_FPS_INACTIVE_STATE_LOW_POWER
-						to set the PMIC state to low
-						power.
-					Absence of this property or other value
-					will not change device state when FPS
-					event get cleared.
-
-Here supported time periods by device in microseconds are as follows:
-MAX77620 supports 40, 80, 160, 320, 640, 1280, 2560 and 5120 microseconds.
-MAX20024 supports 20, 40, 80, 160, 320, 640, 1280 and 2540 microseconds.
-MAX77663 supports 20, 40, 80, 160, 320, 640, 1280 and 2540 microseconds.
-
--maxim,power-ok-control: configure map power ok bit
-			1: Enables POK(Power OK) to control nRST_IO and GPIO1
-			POK function.
-			0: Disables POK control.
-			if property missing, do not configure MPOK bit.
-			If POK mapping is enabled for GPIO1/nRST_IO then,
-			GPIO1/nRST_IO pins are HIGH only if all rails
-			that have POK control enabled are HIGH.
-			If any of the rails goes down(which are enabled for POK
-			control) then, GPIO1/nRST_IO goes LOW.
-			this property is valid for max20024 only.
-
-For DT binding details of different sub modules like GPIO, pincontrol,
-regulator, power, please refer respective device-tree binding document
-under their respective sub-system directories.
-
-Example:
---------
-#include <dt-bindings/mfd/max77620.h>
-
-max77620@3c {
-	compatible = "maxim,max77620";
-	reg = <0x3c>;
-
-	interrupt-parent = <&intc>;
-	interrupts = <0 86 IRQ_TYPE_NONE>;
-
-	interrupt-controller;
-	#interrupt-cells = <2>;
-
-	fps {
-		fps0 {
-			maxim,shutdown-fps-time-period-us = <1280>;
-			maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
-		};
-
-		fps1 {
-			maxim,shutdown-fps-time-period-us = <1280>;
-			maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
-		};
-
-		fps2 {
-			maxim,shutdown-fps-time-period-us = <1280>;
-			maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_SW>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77620.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77620.yaml
new file mode 100644
index 0000000..6027118
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77620.yaml
@@ -0,0 +1,444 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/maxim,max77620.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAX77620 Power management IC from Maxim Semiconductor
+
+maintainers:
+  - Svyatoslav Ryhel <clamor95@gmail.com>
+
+properties:
+  compatible:
+    enum:
+      - maxim,max20024
+      - maxim,max77620
+      - maxim,max77663
+
+  reg:
+    description:
+      Can contain an optional second I2C address pointing to the PMIC's
+      RTC device. If no RTC address is provided, a default address specific
+      to this PMIC will be used.
+    minItems: 1
+    maxItems: 2
+
+  reg-names:
+    items:
+      - const: pmic
+      - const: rtc
+
+  interrupts:
+    maxItems: 1
+
+  interrupt-controller: true
+
+  "#interrupt-cells":
+    const: 2
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description:
+      Device has 8 GPIO pins which can be configured as GPIO as well as
+      the special IO functions. The first cell is the pin number, and the
+      second cell is used to specify the gpio polarity (GPIO_ACTIVE_HIGH or
+      GPIO_ACTIVE_LOW).
+
+  system-power-controller: true
+
+  "#thermal-sensor-cells":
+    const: 0
+    description:
+      Maxim Semiconductor MAX77620 supports alarm interrupts when its
+      die temperature crosses 120C and 140C. These threshold temperatures
+      are not configurable. Device does not provide the real temperature
+      of die other than just indicating whether temperature is above or
+      below threshold level.
+
+  fps:
+    type: object
+    additionalProperties: false
+    description: |
+      The Flexible Power Sequencer (FPS) allows each regulator to power up
+      under hardware or software control. Additionally, each regulator can
+      power on independently or among a group of other regulators with an
+      adjustable power-up and power-down delays (sequencing). GPIO1, GPIO2,
+      and GPIO3 can be programmed to be part of a sequence allowing external
+      regulators to be sequenced along with internal regulators. 32KHz clock
+      can be programmed to be part of a sequence.
+
+      The flexible sequencing structure consists of two hardware enable inputs
+      (EN0, EN1), and 3 master sequencing timers called FPS0, FPS1 and FPS2.
+      Each master sequencing timer is programmable through its configuration
+      register to have a hardware enable source (EN1 or EN2) or a software enable
+      source (SW). When enabled/disabled, the master sequencing timer generates
+      eight sequencing events on different time periods called slots. The time
+      period between each event is programmable within the configuration register.
+      Each regulator, GPIO1, GPIO2, GPIO3, and 32KHz clock has a flexible power
+      sequence slave register which allows its enable source to be specified as
+      a flexible power sequencer timer or a software bit. When a FPS source of
+      regulators, GPIOs and clocks specifies the enable source to be a flexible
+      power sequencer, the power up and power down delays can be specified in
+      the regulators, GPIOs and clocks flexible power sequencer configuration
+      registers.
+
+      When FPS event cleared (set to LOW), regulators, GPIOs and 32KHz clock
+      are set into following state at the sequencing event that corresponds
+      to its flexible sequencer configuration register.
+
+      Sleep state: In this state, regulators, GPIOs and 32KHz clock get disabled
+                   at the sequencing event.
+      Global Low Power Mode (GLPM): In this state, regulators are set in low
+                                    power mode at the sequencing event.
+
+      The configuration parameters of FPS is provided through sub-node "fps"
+      and their child for FPS specific. The child node name for FPS are "fps0",
+      "fps1", and "fps2" for FPS0, FPS1 and FPS2 respectively.
+
+      The FPS configurations like FPS source, power up and power down slots for
+      regulators, GPIOs and 32kHz clocks are provided in their respective
+      configuration nodes which is explained in respective sub-system DT
+      binding document.
+
+      There is need for different FPS configuration parameters based on system
+      state like when system state changed from active to suspend or active to
+      power off (shutdown).
+
+    patternProperties:
+      "^fps[0-2]$":
+        type: object
+        additionalProperties: false
+
+        properties:
+          maxim,fps-event-source:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: |
+              FPS event source like external hardware input to PMIC i.e. EN0, EN1
+              or software (SW).
+
+              The macros are defined on dt-bindings/mfd/max77620.h for different
+              control source.
+                - MAX77620_FPS_EVENT_SRC_EN0 for hardware input pin EN0.
+                - MAX77620_FPS_EVENT_SRC_EN1 for hardware input pin EN1.
+                - MAX77620_FPS_EVENT_SRC_SW for software control.
+
+          maxim,shutdown-fps-time-period-us:
+            description:
+              FPS time period in microseconds when system enters in to shutdown state.
+
+          maxim,suspend-fps-time-period-us:
+            description:
+              FPS time period in microseconds when system enters in to suspend state.
+
+          maxim,device-state-on-disabled-event:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: |
+              Describe the PMIC state when FPS event cleared (set to LOW) whether it
+              should go to sleep state or low-power state. Following are valid values:
+                - MAX77620_FPS_INACTIVE_STATE_SLEEP to set the PMIC state to sleep.
+                - MAX77620_FPS_INACTIVE_STATE_LOW_POWER to set the PMIC state to low
+                  power.
+              Absence of this property or other value will not change device state
+              when FPS event get cleared.
+
+          maxim,power-ok-control:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description: |
+              Configure map power ok bit
+
+              1: Enables POK(Power OK) to control nRST_IO and GPIO1 POK function.
+              0: Disables POK control.
+
+              If property missing, do not configure MPOK bit. If POK mapping is
+              enabled for GPIO1/nRST_IO then, GPIO1/nRST_IO pins are HIGH only if
+              all rails that have POK control enabled are HIGH. If any of the rails
+              goes down (which are enabled for POK control) then, GPIO1/nRST_IO
+              goes LOW.
+            enum: [0, 1]
+
+  pinmux:
+    $ref: /schemas/pinctrl/maxim,max77620-pinctrl.yaml
+
+  regulators:
+    $ref: /schemas/regulator/maxim,max77620-regulator.yaml
+
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - maxim,max20024
+              - maxim,max77663
+    then:
+      properties:
+        "#thermal-sensor-cells": false
+        fps:
+          patternProperties:
+            "^fps[0-2]$":
+              properties:
+                maxim,shutdown-fps-time-period-us:
+                  enum: [20, 40, 80, 160, 320, 640, 1280, 2540]
+                maxim,suspend-fps-time-period-us:
+                  enum: [20, 40, 80, 160, 320, 640, 1280, 2540]
+                maxim,power-ok-control: false
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: maxim,max77620
+    then:
+      properties:
+        fps:
+          patternProperties:
+            "^fps[0-2]$":
+              properties:
+                maxim,shutdown-fps-time-period-us:
+                  enum: [40, 80, 160, 320, 640, 1280, 2560, 5120]
+                maxim,suspend-fps-time-period-us:
+                  enum: [40, 80, 160, 320, 640, 1280, 2560, 5120]
+
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              const: maxim,max77663
+    then:
+      properties:
+        reg-names: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/mfd/max77620.h>
+
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        pmic@3c {
+            compatible = "maxim,max77620";
+            reg = <0x3c>;
+
+            interrupt-parent = <&gpio>;
+            interrupts = <86 IRQ_TYPE_LEVEL_HIGH>;
+
+            interrupt-controller;
+            #interrupt-cells = <2>;
+
+            gpio-controller;
+            #gpio-cells = <2>;
+
+            #thermal-sensor-cells = <0>;
+
+            system-power-controller;
+
+            pinctrl-names = "default";
+            pinctrl-0 = <&max77620_default>;
+
+            max77620_default: pinmux {
+                gpio0 {
+                    pins = "gpio0";
+                    function = "gpio";
+                };
+
+                gpio1 {
+                    pins = "gpio1";
+                    function = "fps-out";
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+                };
+
+                gpio2 {
+                    pins = "gpio2";
+                    function = "fps-out";
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+                };
+
+                gpio3 {
+                    pins = "gpio3";
+                    function = "gpio";
+                };
+
+                gpio4 {
+                    pins = "gpio4";
+                    function = "32k-out1";
+                };
+
+                gpio5-6 {
+                    pins = "gpio5", "gpio6";
+                    function = "gpio";
+                    drive-push-pull = <1>;
+                };
+
+                gpio7 {
+                    pins = "gpio7";
+                    function = "gpio";
+                };
+            };
+
+            fps {
+                fps0 {
+                    maxim,shutdown-fps-time-period-us = <1280>;
+                    maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN0>;
+                };
+
+                fps1 {
+                    maxim,shutdown-fps-time-period-us = <1280>;
+                    maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_EN1>;
+                };
+
+                fps2 {
+                    maxim,shutdown-fps-time-period-us = <1280>;
+                    maxim,fps-event-source = <MAX77620_FPS_EVENT_SRC_SW>;
+                };
+            };
+
+            regulators {
+                in-sd0-supply = <&vdd_5v0_vbus>;
+                in-sd1-supply = <&vdd_5v0_vbus>;
+                in-sd2-supply = <&vdd_5v0_vbus>;
+                in-sd3-supply = <&vdd_5v0_vbus>;
+
+                in-ldo0-1-supply = <&vdd_1v8_vio>;
+                in-ldo2-supply   = <&vdd_3v3_vbat>;
+                in-ldo3-5-supply = <&vdd_3v3_vbat>;
+                in-ldo4-6-supply = <&vdd_3v3_vbat>;
+                in-ldo7-8-supply = <&vdd_1v8_vio>;
+
+                sd0 {
+                    regulator-name = "vdd_cpu";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <1250000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                sd1 {
+                    regulator-name = "vdd_core";
+                    regulator-min-microvolt = <950000>;
+                    regulator-max-microvolt = <1350000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+                };
+
+                vdd_1v8_vio: sd2 {
+                    regulator-name = "vdd_1v8_gen";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                sd3 {
+                    regulator-name = "vddio_ddr";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <1200000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo0 {
+                    regulator-name = "avdd_pll";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <1200000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
+                };
+
+                ldo1 {
+                    regulator-name = "vdd_ddr_hs";
+                    regulator-min-microvolt = <1000000>;
+                    regulator-max-microvolt = <1000000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo2 {
+                    regulator-name = "avdd_usb";
+                    regulator-min-microvolt = <3300000>;
+                    regulator-max-microvolt = <3300000>;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo3 {
+                    regulator-name = "vdd_sdmmc3";
+                    regulator-min-microvolt = <3000000>;
+                    regulator-max-microvolt = <3000000>;
+                    regulator-always-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo4 {
+                    regulator-name = "vdd_rtc";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <1200000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+                };
+
+                ldo5 {
+                    regulator-name = "vdd_ddr_rx";
+                    regulator-min-microvolt = <2850000>;
+                    regulator-max-microvolt = <2850000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
+                };
+
+                ldo6 {
+                    regulator-name = "avdd_osc";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                    regulator-always-on;
+                    regulator-boot-on;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo7 {
+                    regulator-name = "vdd_1v2_mhl";
+                    regulator-min-microvolt = <1050000>;
+                    regulator-max-microvolt = <1250000>;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+
+                ldo8 {
+                    regulator-name = "avdd_dsi_csi";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <1200000>;
+
+                    maxim,active-fps-source = <MAX77620_FPS_SRC_NONE>;
+                };
+            };
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/mfd/maxim,max77759.yaml b/Documentation/devicetree/bindings/mfd/maxim,max77759.yaml
index 525de9ab..42e4a84 100644
--- a/Documentation/devicetree/bindings/mfd/maxim,max77759.yaml
+++ b/Documentation/devicetree/bindings/mfd/maxim,max77759.yaml
@@ -16,6 +16,9 @@
   The MAX77759 includes Battery Charger, Fuel Gauge, temperature sensors, USB
   Type-C Port Controller (TCPC), NVMEM, and a GPIO expander.
 
+allOf:
+  - $ref: /schemas/power/supply/power-supply.yaml#
+
 properties:
   compatible:
     const: maxim,max77759
@@ -37,12 +40,18 @@
   nvmem-0:
     $ref: /schemas/nvmem/maxim,max77759-nvmem.yaml
 
+  chgin-otg-regulator:
+    type: object
+    description: Provides Boost for sourcing VBUS.
+    $ref: /schemas/regulator/regulator.yaml#
+    unevaluatedProperties: false
+
 required:
   - compatible
   - interrupts
   - reg
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
@@ -59,6 +68,11 @@
 
             interrupt-controller;
             #interrupt-cells = <2>;
+            power-supplies = <&maxtcpci>;
+
+            chgin-otg-regulator {
+                regulator-name = "chgin-otg";
+            };
 
             gpio {
                 compatible = "maxim,max77759-gpio";
diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
index e5931d1..644c42b 100644
--- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml
@@ -135,6 +135,7 @@
   "^adc@[0-9a-f]+$":
     type: object
     oneOf:
+      - $ref: /schemas/iio/adc/qcom,spmi-adc5-gen3.yaml#
       - $ref: /schemas/iio/adc/qcom,spmi-iadc.yaml#
       - $ref: /schemas/iio/adc/qcom,spmi-rradc.yaml#
       - $ref: /schemas/iio/adc/qcom,spmi-vadc.yaml#
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml
index 9f42097d..b094542 100644
--- a/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml
+++ b/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml
@@ -4,19 +4,19 @@
 $id: http://devicetree.org/schemas/mfd/rohm,bd72720-pmic.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title: ROHM BD72720 Power Management Integrated Circuit
+title: ROHM BD72720 and BD73900 Power Management Integrated Circuits
 
 maintainers:
   - Matti Vaittinen <mazziesaccount@gmail.com>
 
 description:
-  BD72720 is a single-chip power management IC for battery-powered portable
-  devices. The BD72720 integrates 10 bucks and 11 LDOs, and a 3000 mA
-  switching charger. The IC also includes a Coulomb counter, a real-time
-  clock (RTC), GPIOs and a 32.768 kHz clock gate.
+  BD72720 and BD73900 are single-chip power management ICs for
+  battery-powered portable devices. They integrate 10 bucks and 11 LDOs,
+  and a 3000 mA switching charger. ICs also include a Coulomb counter,
+  a real-time clock (RTC), GPIOs and a 32.768 kHz clock gate.
 
-# In addition to the properties found from the charger node, the ROHM BD72720
-# uses properties from a static battery node. Please see the:
+# In addition to the properties found from the charger node, PMICs
+# use properties from a static battery node. Please see the:
 # Documentation/devicetree/bindings/power/supply/battery.yaml
 #
 # Following properties are used
@@ -48,7 +48,12 @@
 
 properties:
   compatible:
-    const: rohm,bd72720
+    oneOf:
+      - const: rohm,bd72720
+
+      - items:
+          - const: rohm,bd73900
+          - const: rohm,bd72720
 
   reg:
     description:
@@ -84,7 +89,7 @@
     minimum: 10000
     maximum: 50000
     description:
-      BD72720 has a SAR ADC for measuring charging currents. External sense
+      PMIC has a SAR ADC for measuring charging currents. External sense
       resistor (RSENSE in data sheet) should be used. If some other but
       30 mOhm resistor is used the resistance value should be given here in
       micro Ohms.
@@ -100,7 +105,7 @@
   rohm,pin-fault_b:
     $ref: /schemas/types.yaml#/definitions/string
     description:
-      BD72720 has an OTP option to use fault_b-pin for different
+      PMIC has an OTP option to use fault_b-pin for different
       purposes. Set this property accordingly. OTP options are
       OTP0 - bi-directional FAULT_B or READY indicator depending on a
       'sub option'
@@ -116,7 +121,7 @@
   "^rohm,pin-dvs[0-1]$":
     $ref: /schemas/types.yaml#/definitions/string
     description:
-      BD72720 has 4 different OTP options to determine the use of dvs<X>-pins.
+      PMIC has 4 different OTP options to determine the use of dvs<X>-pins.
       OTP0 - regulator RUN state control.
       OTP1 - GPI.
       OTP2 - GPO.
@@ -130,7 +135,7 @@
 
   "^rohm,pin-exten[0-1]$":
     $ref: /schemas/types.yaml#/definitions/string
-    description: BD72720 has an OTP option to use exten0-pin for different
+    description: PMIC has an OTP option to use exten0-pin for different
       purposes. Set this property accordingly.
       OTP0 - GPO
       OTP1 - Power sequencer output.
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index e57add2..e228670 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -61,6 +61,7 @@
           - cirrus,ep7209-syscon2
           - cirrus,ep7209-syscon3
           - cnxt,cx92755-uc
+          - econet,en751221-chip-scu
           - freecom,fsg-cs2-system-controller
           - fsl,imx93-aonmix-ns-syscfg
           - fsl,imx93-wakeupmix-syscfg
@@ -173,6 +174,7 @@
               - cirrus,ep7209-syscon2
               - cirrus,ep7209-syscon3
               - cnxt,cx92755-uc
+              - econet,en751221-chip-scu
               - freecom,fsg-cs2-system-controller
               - fsl,imx93-aonmix-ns-syscfg
               - fsl,imx93-wakeupmix-syscfg
diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
index d8e47db6..ca830dd 100644
--- a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
+++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml
@@ -18,9 +18,14 @@
 
 properties:
   compatible:
-    enum:
-      - qcom,kaanapali-fastrpc
-      - qcom,fastrpc
+    oneOf:
+      - enum:
+          - qcom,kaanapali-fastrpc
+          - qcom,fastrpc
+      - items:
+          - enum:
+              - qcom,glymur-fastrpc
+          - const: qcom,kaanapali-fastrpc
 
   label:
     enum:
diff --git a/Documentation/devicetree/bindings/misc/ti,fpc202.yaml b/Documentation/devicetree/bindings/misc/ti,fpc202.yaml
index a8cb10f..71c5859 100644
--- a/Documentation/devicetree/bindings/misc/ti,fpc202.yaml
+++ b/Documentation/devicetree/bindings/misc/ti,fpc202.yaml
@@ -53,6 +53,22 @@
 
     unevaluatedProperties: false
 
+  "^led@1[4-b]$":
+    $ref: /schemas/leds/common.yaml#
+    description: Output GPIO line with advanced LED features enabled.
+
+    properties:
+      reg:
+        minimum: 0x14
+        maximum: 0x1b
+        description:
+          GPIO line ID
+
+    required:
+      - reg
+
+    unevaluatedProperties: false
+
 required:
   - compatible
   - reg
@@ -89,6 +105,11 @@
                 #size-cells = <0>;
                 reg = <1>;
             };
+
+            led@14 {
+                reg = <0x14>;
+                label = "phy0:green:indicator";
+            };
         };
     };
 ...
diff --git a/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml
index 80b5a6c..4ca75ed 100644
--- a/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml
+++ b/Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml
@@ -9,7 +9,7 @@
 description: Exports a series of SPMI registers as NVMEM cells
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 allOf:
   - $ref: nvmem.yaml#
diff --git a/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml b/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
index afd1919..c713e23 100644
--- a/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
+++ b/Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml
@@ -19,12 +19,7 @@
 
 properties:
   compatible:
-    oneOf:
-      - items:
-          - enum:
-              - kontron,sa67-vpd
-          - const: kontron,sl28-vpd
-      - const: kontron,sl28-vpd
+    const: kontron,sl28-vpd
 
   serial-number:
     type: object
diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
index 839513d..2ab047f 100644
--- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
+++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
@@ -26,6 +26,7 @@
           - qcom,ipq8064-qfprom
           - qcom,ipq8074-qfprom
           - qcom,ipq9574-qfprom
+          - qcom,kaanapali-qfprom
           - qcom,msm8226-qfprom
           - qcom,msm8916-qfprom
           - qcom,msm8917-qfprom
diff --git a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
index dc89020..7e4d5e1 100644
--- a/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
+++ b/Documentation/devicetree/bindings/nvmem/rockchip,otp.yaml
@@ -14,6 +14,9 @@
     enum:
       - rockchip,px30-otp
       - rockchip,rk3308-otp
+      - rockchip,rk3528-otp
+      - rockchip,rk3562-otp
+      - rockchip,rk3568-otp
       - rockchip,rk3576-otp
       - rockchip,rk3588-otp
 
@@ -26,19 +29,15 @@
 
   clock-names:
     minItems: 3
-    items:
-      - const: otp
-      - const: apb_pclk
-      - const: phy
-      - const: arb
+    maxItems: 4
 
   resets:
     minItems: 1
-    maxItems: 3
+    maxItems: 4
 
   reset-names:
     minItems: 1
-    maxItems: 3
+    maxItems: 4
 
 required:
   - compatible
@@ -64,7 +63,10 @@
         clocks:
           maxItems: 3
         clock-names:
-          maxItems: 3
+          items:
+            - const: otp
+            - const: apb_pclk
+            - const: phy
         resets:
           maxItems: 1
         reset-names:
@@ -76,13 +78,68 @@
         compatible:
           contains:
             enum:
+              - rockchip,rk3528-otp
+    then:
+      properties:
+        clocks:
+          maxItems: 3
+        clock-names:
+          items:
+            - const: otp
+            - const: apb_pclk
+            - const: sbpi
+        resets:
+          minItems: 3
+          maxItems: 3
+        reset-names:
+          items:
+            - const: otp
+            - const: apb
+            - const: sbpi
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - rockchip,rk3562-otp
+              - rockchip,rk3568-otp
+    then:
+      properties:
+        clocks:
+          minItems: 4
+          maxItems: 4
+        clock-names:
+          items:
+            - const: otp
+            - const: apb_pclk
+            - const: phy
+            - const: sbpi
+        resets:
+          minItems: 4
+          maxItems: 4
+        reset-names:
+          items:
+            - const: otp
+            - const: apb
+            - const: phy
+            - const: sbpi
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
               - rockchip,rk3576-otp
     then:
       properties:
         clocks:
           maxItems: 3
         clock-names:
-          maxItems: 3
+          items:
+            - const: otp
+            - const: apb_pclk
+            - const: phy
         resets:
           minItems: 2
           maxItems: 2
@@ -101,10 +158,16 @@
       properties:
         clocks:
           minItems: 4
+          maxItems: 4
         clock-names:
-          minItems: 4
+          items:
+            - const: otp
+            - const: apb_pclk
+            - const: phy
+            - const: arb
         resets:
           minItems: 3
+          maxItems: 3
         reset-names:
           items:
             - const: otp
diff --git a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
index 665ec79..4107317 100644
--- a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
@@ -18,7 +18,9 @@
   compatible:
     oneOf:
       - items:
-          - const: apple,t6020-pinctrl
+          - enum:
+              - apple,t6020-pinctrl
+              - apple,t8122-pinctrl
           - const: apple,t8103-pinctrl
       - items:
           # Do not add additional SoC to this list.
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx27-iomuxc.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx27-iomuxc.yaml
new file mode 100644
index 0000000..1254bfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx27-iomuxc.yaml
@@ -0,0 +1,126 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/fsl,imx27-iomuxc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale i.MX1/i.MX25/i.MX27 IOMUX Controller
+
+maintainers:
+  - Frank Li <Frank.Li@nxp.com>
+
+description:
+  Please refer to fsl,imx-pinctrl.txt and pinctrl-bindings.txt in this directory
+  for common binding part and usage.
+
+properties:
+  compatible:
+    enum:
+      - fsl,imx1-iomuxc
+      - fsl,imx27-iomuxc
+
+  reg:
+    maxItems: 1
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  '^gpio@[0-9a-f]+$':
+    type: object
+    $ref: /schemas/gpio/fsl-imx-gpio.yaml
+    unevaluatedProperties: false
+
+  'grp$':
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+
+    properties:
+      fsl,pins:
+        description:
+          three integers array, represents a group of pins mux and config
+          setting. The format is fsl,pins = <PIN MUX_ID CONFIG>.
+        $ref: /schemas/types.yaml#/definitions/uint32-matrix
+        items:
+          items:
+            - description:
+                PIN is an integer between 0 and 0xbf. imx27 has 6 ports with 32
+                configurable pins each. PIN is PORT * 32 + PORT_PIN, PORT_PIN
+                is the pin number on the specific port (between 0 and 31)
+            - description: |
+                MUX_ID is function + (direction << 2) + (gpio_oconf << 4)
+                + (gpio_iconfa << 8) + (gpio_iconfb << 10)
+
+                function value is used to select the pin function.
+                Possible values:
+                  0 - Primary function
+                  1 - Alternate function
+                  2 - GPIO
+                Registers: GIUS (GPIO In Use), GPR (General Purpose Register)
+
+                direction defines the data direction of the pin.
+                Possible values:
+                  0 - Input
+                  1 - Output
+                Register: DDIR
+
+                gpio_oconf configures the gpio submodule output signal.
+                This does not have any effect unless GPIO function is
+                selected. A/B/C_IN are output signals of function blocks
+                A,B and C. Specific function blocks are described in the
+                reference manual.
+                Possible values:
+                  0 - A_IN
+                  1 - B_IN
+                  2 - C_IN
+                  3 - Data Register
+                Registers: OCR1, OCR2
+
+                gpio_iconfa/b configures the gpio submodule input to
+                functionblocks A and B. GPIO function should be selected if
+                this is configured.
+                Possible values:
+                  0 - GPIO_IN
+                  1 - Interrupt Status Register
+                  2 - Pulldown
+                  3 - Pullup
+                Registers ICONFA1, ICONFA2, ICONFB1 and ICONFB2
+
+            - description:
+                CONFIG can be 0 or 1, meaning Pullup disable/enable.
+    required:
+      - fsl,pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+allOf:
+  - $ref: pinctrl.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    pinmux@10015000 {
+        compatible = "fsl,imx27-iomuxc";
+        reg = <0x10015000 0x600>;
+
+        uartgrp {
+            fsl,pins = <
+                0x8c 0x004 0x0 /* UART1_TXD__UART1_TXD */
+                0x8d 0x000 0x0 /* UART1_RXD__UART1_RXD */
+                0x8e 0x004 0x0 /* UART1_CTS__UART1_CTS */
+                0x8f 0x000 0x0 /* UART1_RTS__UART1_RTS */
+            >;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt
deleted file mode 100644
index d1706ea..0000000
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx27-pinctrl.txt
+++ /dev/null
@@ -1,121 +0,0 @@
-* Freescale IMX27 IOMUX Controller
-
-Required properties:
-- compatible: "fsl,imx27-iomuxc"
-
-The iomuxc driver node should define subnodes containing of pinctrl configuration subnodes.
-
-Required properties for pin configuration node:
-- fsl,pins: three integers array, represents a group of pins mux and config
-  setting. The format is fsl,pins = <PIN MUX_ID CONFIG>.
-
-  PIN is an integer between 0 and 0xbf. imx27 has 6 ports with 32 configurable
-  configurable pins each. PIN is PORT * 32 + PORT_PIN, PORT_PIN is the pin
-  number on the specific port (between 0 and 31).
-
-  MUX_ID is
-    function + (direction << 2) + (gpio_oconf << 4) + (gpio_iconfa << 8) + (gpio_iconfb << 10)
-
-      function value is used to select the pin function.
-      Possible values:
-          0 - Primary function
-          1 - Alternate function
-          2 - GPIO
-      Registers: GIUS (GPIO In Use), GPR (General Purpose Register)
-
-      direction defines the data direction of the pin.
-      Possible values:
-          0 - Input
-          1 - Output
-      Register: DDIR
-
-      gpio_oconf configures the gpio submodule output signal. This does not
-      have any effect unless GPIO function is selected. A/B/C_IN are output
-      signals of function blocks A,B and C. Specific function blocks are
-      described in the reference manual.
-      Possible values:
-          0 - A_IN
-          1 - B_IN
-          2 - C_IN
-          3 - Data Register
-      Registers: OCR1, OCR2
-
-      gpio_iconfa/b configures the gpio submodule input to functionblocks A and
-      B. GPIO function should be selected if this is configured.
-      Possible values:
-          0 - GPIO_IN
-          1 - Interrupt Status Register
-          2 - Pulldown
-          3 - Pullup
-      Registers ICONFA1, ICONFA2, ICONFB1 and ICONFB2
-
-  CONFIG can be 0 or 1, meaning Pullup disable/enable.
-
-
-The iomux controller has gpio child nodes which are embedded in the iomux
-control registers. They have to be defined as child nodes of the iomux device
-node. If gpio subnodes are defined "#address-cells", "#size-cells" and "ranges"
-properties for the iomux device node are required.
-
-Example:
-
-iomuxc: iomuxc@10015000 {
-	compatible = "fsl,imx27-iomuxc";
-	reg = <0x10015000 0x600>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges;
-
-	gpio1: gpio@10015000 {
-		...
-	};
-
-	...
-
-	uart {
-		pinctrl_uart1: uart-1 {
-			fsl,pins = <
-				0x8c 0x004 0x0 /* UART1_TXD__UART1_TXD */
-				0x8d 0x000 0x0 /* UART1_RXD__UART1_RXD */
-				0x8e 0x004 0x0 /* UART1_CTS__UART1_CTS */
-				0x8f 0x000 0x0 /* UART1_RTS__UART1_RTS */
-			>;
-		};
-
-		...
-	};
-};
-
-
-For convenience there are macros defined in imx27-pinfunc.h which provide PIN
-and MUX_ID. They are structured as MX27_PAD_<Pad name>__<Signal name>. The names
-are defined in the i.MX27 reference manual.
-
-The above example using macros:
-
-iomuxc: iomuxc@10015000 {
-	compatible = "fsl,imx27-iomuxc";
-	reg = <0x10015000 0x600>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	ranges;
-
-	gpio1: gpio@10015000 {
-		...
-	};
-
-	...
-
-	uart {
-		pinctrl_uart1: uart-1 {
-			fsl,pins = <
-				MX27_PAD_UART1_TXD__UART1_TXD 0x0
-				MX27_PAD_UART1_RXD__UART1_RXD 0x0
-				MX27_PAD_UART1_CTS__UART1_CTS 0x0
-				MX27_PAD_UART1_RTS__UART1_RTS 0x0
-			>;
-		};
-
-		...
-	};
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/fsl,imx35-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/fsl,imx35-pinctrl.yaml
index 265c43a..846e110 100644
--- a/Documentation/devicetree/bindings/pinctrl/fsl,imx35-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/fsl,imx35-pinctrl.yaml
@@ -20,6 +20,7 @@
   compatible:
     oneOf:
       - enum:
+          - fsl,imx25-iomuxc
           - fsl,imx35-iomuxc
           - fsl,imx51-iomuxc
           - fsl,imx53-iomuxc
diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml
index 4f9013d..727da7f 100644
--- a/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,armada3710-xb-pinctrl.yaml
@@ -84,11 +84,12 @@
 
     properties:
       groups:
-        enum: [ emmc_nb, i2c1, i2c2, jtag, mii_col, onewire, pcie1,
-                pcie1_clkreq, pcie1_wakeup, pmic0, pmic1, ptp, ptp_clk,
-                ptp_trig, pwm0, pwm1, pwm2, pwm3, rgmii, sdio0, sdio_sb, smi,
-                spi_cs1, spi_cs2, spi_cs3, spi_quad, uart1, uart2,
-                usb2_drvvbus1, usb32_drvvbus0 ]
+        items:
+          enum: [ emmc_nb, i2c1, i2c2, jtag, mii_col, onewire, pcie1,
+                  pcie1_clkreq, pcie1_wakeup, pmic0, pmic1, ptp, ptp_clk,
+                  ptp_trig, pwm0, pwm1, pwm2, pwm3, rgmii, sdio0, sdio_sb,
+                  smi, spi_cs1, spi_cs2, spi_cs3, spi_quad, uart1, uart2,
+                  usb2_drvvbus1, usb32_drvvbus0 ]
 
       function:
         enum: [ drvbus, emmc, gpio, i2c, jtag, led, mii, mii_err, onewire,
diff --git a/Documentation/devicetree/bindings/pinctrl/maxim,max77620-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/maxim,max77620-pinctrl.yaml
new file mode 100644
index 0000000..b3ea364
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/maxim,max77620-pinctrl.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/maxim,max77620-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Pinmux controller function for Maxim MAX77620 Power management IC
+
+maintainers:
+  - Svyatoslav Ryhel <clamor95@gmail.com>
+
+description:
+  Device has 8 GPIO pins which can be configured as GPIO as well as the
+  special IO functions.
+
+allOf:
+  - $ref: /schemas/pinctrl/pincfg-node.yaml
+  - $ref: /schemas/pinctrl/pinmux-node.yaml
+
+patternProperties:
+  "^(pin|gpio).":
+    type: object
+    additionalProperties: false
+
+    properties:
+      pins:
+        items:
+          enum: [ gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7 ]
+
+      function:
+        items:
+          enum: [ gpio, lpm-control-in, fps-out, 32k-out1, sd0-dvs-in, sd1-dvs-in,
+                  reference-out ]
+
+      drive-push-pull: true
+      drive-open-drain: true
+      bias-pull-up: true
+      bias-pull-down: true
+
+      maxim,active-fps-source:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description: |
+          FPS source for the GPIOs to get enabled/disabled when system is in
+          active state. Valid values are:
+          - MAX77620_FPS_SRC_0: FPS source is FPS0.
+          - MAX77620_FPS_SRC_1: FPS source is FPS1
+          - MAX77620_FPS_SRC_2: FPS source is FPS2
+          - MAX77620_FPS_SRC_NONE: GPIO is not controlled by FPS events and
+                                   it gets enabled/disabled by register access.
+          Absence of this property will leave the FPS configuration register
+          for that GPIO to default configuration.
+
+      maxim,active-fps-power-up-slot:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Sequencing event slot number on which the GPIO get enabled when
+          master FPS input event set to HIGH. This is applicable if FPS source
+          is selected as FPS0, FPS1 or FPS2.
+        enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+      maxim,active-fps-power-down-slot:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          Sequencing event slot number on which the GPIO get disabled when
+          master FPS input event set to LOW. This is applicable if FPS source
+          is selected as FPS0, FPS1 or FPS2.
+        enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+      maxim,suspend-fps-source:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          This is same as property "maxim,active-fps-source" but value get
+          configured when system enters in to suspend state.
+
+      maxim,suspend-fps-power-up-slot:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          This is same as property "maxim,active-fps-power-up-slot" but this
+          value get configured into FPS configuration register when system
+          enters into suspend. This is applicable if suspend state FPS source
+          is selected as FPS0, FPS1 or FPS2.
+        enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+      maxim,suspend-fps-power-down-slot:
+        $ref: /schemas/types.yaml#/definitions/uint32
+        description:
+          This is same as property "maxim,active-fps-power-down-slot" but this
+          value get configured into FPS configuration register when system
+          enters into suspend. This is applicable if suspend state FPS source
+          is selected as FPS0, FPS1 or FPS2.
+        enum: [0, 1, 2, 3, 4, 5, 6, 7]
+
+    required:
+      - pins
+
+additionalProperties: false
+
+# see maxim,max77620.yaml for an example
diff --git a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml
index a916d0f..97dbce8 100644
--- a/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pincfg-node.yaml
@@ -162,12 +162,105 @@
       this affects the expected delay in ps before latching a value to
       an output pin.
 
-if:
-  required:
-    - skew-delay
-then:
-  properties:
-    skew-delay-input-ps: false
-    skew-delay-output-ps: false
+  input-threshold-voltage-microvolt:
+    description: Specifies the input voltage level of the pin in microvolts.
+      This defines the reference for  VIH (Input High Voltage) and VIL
+      (Input Low Voltage) thresholds for proper signal detection.
+
+allOf:
+  - if:
+      required:
+        - skew-delay
+    then:
+      properties:
+        skew-delay-input-ps: false
+        skew-delay-output-ps: false
+
+  - if:
+      required:
+        - input-disable
+    then:
+      properties:
+        input-enable: false
+        input-threshold-voltage-microvolt: false
+
+  - if:
+      required:
+        - output-disable
+    then:
+      properties:
+        output-enable: false
+        output-impedance-ohms: false
+
+  - if:
+      required:
+        - output-low
+    then:
+      properties:
+        output-high: false
+
+  - if:
+      required:
+        - low-power-enable
+    then:
+      properties:
+        low-power-disable: false
+
+  - if:
+      required:
+        - input-schmitt-disable
+    then:
+      properties:
+        input-schmitt-enable: false
+        input-schmitt-microvolt: false
+
+  - if:
+      required:
+        - drive-strength
+    then:
+      properties:
+        drive-strength-microamp: false
+
+  - if:
+      anyOf:
+        - required:
+            - drive-open-source
+        - required:
+            - drive-open-drain
+        - required:
+            - drive-push-pull
+    then:
+      oneOf:
+        - required:
+            - drive-open-source
+        - required:
+            - drive-open-drain
+        - required:
+            - drive-push-pull
+
+  - if:
+      anyOf:
+        - required:
+            - bias-disable
+        - required:
+            - bias-bus-hold
+        - required:
+            - bias-pull-up
+        - required:
+            - bias-pull-down
+        - required:
+            - bias-pull-pin-default
+    then:
+      oneOf:
+        - required:
+            - bias-disable
+        - required:
+            - bias-bus-hold
+        - required:
+            - bias-pull-up
+        - required:
+            - bias-pull-down
+        - required:
+            - bias-pull-pin-default
 
 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt
deleted file mode 100644
index 28fbca1..0000000
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-max77620.txt
+++ /dev/null
@@ -1,127 +0,0 @@
-Pincontrol driver for MAX77620 Power management IC from Maxim Semiconductor.
-
-Device has 8 GPIO pins which can be configured as GPIO as well as the
-special IO functions.
-
-Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
-for details of the common pinctrl bindings used by client devices,
-including the meaning of the phrase "pin configuration node".
-
-Optional Pinmux properties:
---------------------------
-Following properties are required if default setting of pins are required
-at boot.
-- pinctrl-names: A pinctrl state named per <pinctrl-bindings.txt>.
-- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
-		<pinctrl-bindings.txt>.
-
-The pin configurations are defined as child of the pinctrl states node. Each
-sub-node have following properties:
-
-Required properties:
-------------------
-- pins: List of pins. Valid values of pins properties are:
-		      gpio0, gpio1, gpio2, gpio3, gpio4, gpio5, gpio6, gpio7.
-
-Optional properties:
--------------------
-Following are optional properties defined as pinmux DT binding document
-<pinctrl-bindings.txt>. Absence of properties will leave the configuration
-on default.
-	function,
-	drive-push-pull,
-	drive-open-drain,
-	bias-pull-up,
-	bias-pull-down.
-
-Valid values for function properties are:
-	gpio, lpm-control-in, fps-out, 32k-out, sd0-dvs-in, sd1-dvs-in,
-	reference-out
-
-There are also customised properties for the GPIO1, GPIO2 and GPIO3. These
-customised properties are required to configure FPS configuration parameters
-of these GPIOs. Please refer <devicetree/bindings/mfd/max77620.txt> for more
-detail of Flexible Power Sequence (FPS).
-
-- maxim,active-fps-source:		FPS source for the GPIOs to get
-					enabled/disabled when system is in
-					active state.  Valid values are:
-					- MAX77620_FPS_SRC_0,
-						FPS source is FPS0.
-					- MAX77620_FPS_SRC_1,
-						FPS source is FPS1
-					- MAX77620_FPS_SRC_2 and
-						FPS source is FPS2
-					- MAX77620_FPS_SRC_NONE.
-						GPIO is not controlled
-						by FPS events and it gets
-						enabled/disabled by register
-						access.
-					Absence of this property will leave
-					the FPS configuration register for that
-					GPIO to default configuration.
-
-- maxim,active-fps-power-up-slot:	Sequencing event slot number on which
-					the GPIO get enabled when
-					master FPS input event set to HIGH.
-					Valid values are 0 to 7.
-					This is applicable if FPS source is
-					selected as FPS0, FPS1 or FPS2.
-
-- maxim,active-fps-power-down-slot:	Sequencing event slot number on which
-					the GPIO get disabled when master
-					FPS input event set to LOW.
-					Valid values are 0 to 7.
-					This is applicable if FPS source is
-					selected as FPS0, FPS1 or FPS2.
-
-- maxim,suspend-fps-source:		This is same as property
-					"maxim,active-fps-source" but value
-					get configured when system enters in
-					to suspend state.
-
-- maxim,suspend-fps-power-up-slot:	This is same as property
-					"maxim,active-fps-power-up-slot" but
-					this value get configured into FPS
-					configuration register when system
-					enters into suspend.
-					This is applicable if suspend state
-					FPS source is selected as FPS0, FPS1 or
-
-- maxim,suspend-fps-power-down-slot:	This is same as property
-					"maxim,active-fps-power-down-slot" but
-					this value get configured into FPS
-					configuration register when system
-					enters into suspend.
-					This is applicable if suspend state
-					FPS source is selected as FPS0, FPS1 or
-					FPS2.
-
-Example:
---------
-#include <dt-bindings/mfd/max77620.h>
-...
-max77620@3c {
-
-	pinctrl-names = "default";
-	pinctrl-0 = <&spmic_default>;
-
-	spmic_default: pinmux@0 {
-		pin_gpio0 {
-			pins = "gpio0";
-			function = "gpio";
-		};
-
-		pin_gpio1 {
-			pins = "gpio1";
-			function = "fps-out";
-			maxim,active-fps-source = <MAX77620_FPS_SRC_0>;
-		};
-
-		pin_gpio2 {
-			pins = "gpio2";
-			function = "fps-out";
-			maxim,active-fps-source = <MAX77620_FPS_SRC_1>;
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml
index 9135788..afe7329 100644
--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-single.yaml
@@ -38,6 +38,10 @@
           - enum:
               - marvell,pxa1908-padconf
           - const: pinconf-single
+      - items:
+          - enum:
+              - brcm,bcm7038-padconf
+          - const: pinctrl-single
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,eliza-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,eliza-tlmm.yaml
new file mode 100644
index 0000000..2826504
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,eliza-tlmm.yaml
@@ -0,0 +1,138 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,eliza-tlmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Eliza TLMM block
+
+maintainers:
+  - Abel Vesa <abel.vesa@oss.qualcomm.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in Qualcomm Eliza SoC.
+
+allOf:
+  - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,eliza-tlmm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 93
+
+  gpio-line-names:
+    maxItems: 185
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-eliza-tlmm-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-eliza-tlmm-state"
+        additionalProperties: false
+
+$defs:
+  qcom-eliza-tlmm-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          oneOf:
+            - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-7][0-9]|18[0-4])$"
+            - enum: [ ufs_reset ]
+        minItems: 1
+        maxItems: 36
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+        enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk0,
+                audio_ref_clk, cam_mclk, cci_async_in, cci_i2c_scl,
+                cci_i2c_sda, cci_timer, coex_uart1_rx, coex_uart1_tx,
+                coex_uart2_rx, coex_uart2_tx, dbg_out_clk,
+                ddr_bist_complete, ddr_bist_fail, ddr_bist_start,
+                ddr_bist_stop, ddr_pxi0, ddr_pxi1, dp0_hot, egpio,
+                gcc_gp1, gcc_gp2, gcc_gp3, gnss_adc0, gnss_adc1,
+                hdmi_ddc_scl, hdmi_ddc_sda, hdmi_dtest0, hdmi_dtest1,
+                hdmi_hot_plug, hdmi_pixel_clk, hdmi_rcv_det, hdmi_tx_cec,
+                host2wlan_sol, i2s0_data0, i2s0_data1, i2s0_sck, i2s0_ws,
+                ibi_i3c, jitter_bist, mdp_esync0_out, mdp_esync1_out,
+                mdp_vsync, mdp_vsync0_out, mdp_vsync11_out,
+                mdp_vsync1_out, mdp_vsync2_out, mdp_vsync3_out,
+                mdp_vsync_e, nav_gpio0, nav_gpio1, nav_gpio2, nav_gpio3,
+                pcie0_clk_req_n, pcie1_clk_req_n, phase_flag,
+                pll_bist_sync, pll_clk_aux, prng_rosc0, prng_rosc1,
+                prng_rosc2, prng_rosc3, qdss_cti, qdss_gpio_traceclk,
+                qdss_gpio_tracectl, qdss_gpio_tracedata, qlink_big_enable,
+                qlink_big_request, qlink_little_enable,
+                qlink_little_request, qlink_wmss, qspi0, qspi_clk,
+                qspi_cs, qup1_se0, qup1_se1, qup1_se2, qup1_se3, qup1_se4,
+                qup1_se5, qup1_se6, qup1_se7, qup2_se0, qup2_se1,
+                qup2_se2, qup2_se3, qup2_se4, qup2_se5, qup2_se6,
+                qup2_se7, resout_gpio, sd_write_protect, sdc1, sdc2,
+                sdc2_fb_clk, tb_trig_sdc1, tb_trig_sdc2, tmess_prng0,
+                tmess_prng1, tmess_prng2, tmess_prng3, tsense_pwm1,
+                tsense_pwm2, tsense_pwm3, tsense_pwm4, uim0_clk,
+                uim0_data, uim0_present, uim0_reset, uim1_clk, uim1_data,
+                uim1_present, uim1_reset, usb0_hs, usb_phy, vfr_0, vfr_1,
+                vsense_trigger_mirnat, wcn_sw_ctrl ]
+    required:
+      - pins
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tlmm: pinctrl@f100000 {
+        compatible = "qcom,eliza-tlmm";
+        reg = <0x0f100000 0x300000>;
+
+        interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+
+        gpio-controller;
+        #gpio-cells = <2>;
+
+        interrupt-controller;
+        #interrupt-cells = <2>;
+
+        gpio-ranges = <&tlmm 0 0 186>;
+
+        gpio-wo-state {
+            pins = "gpio1";
+            function = "gpio";
+        };
+
+        qup-uart14-default-state {
+            pins = "gpio18", "gpio19";
+            function = "qup2_se5";
+            drive-strength = <2>;
+            bias-disable;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml
new file mode 100644
index 0000000..3b39617
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,hawi-tlmm.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,hawi-tlmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Technologies, Inc. Hawi TLMM block
+
+maintainers:
+  - Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in Qualcomm Hawi SoC.
+
+allOf:
+  - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,hawi-tlmm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 113
+
+  gpio-line-names:
+    maxItems: 226
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-hawi-tlmm-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-hawi-tlmm-state"
+        additionalProperties: false
+
+$defs:
+  qcom-hawi-tlmm-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          oneOf:
+            - pattern: "^gpio([0-9]|[1-9][0-9]|1[0-9][0-9]|20[0-9]|21[0-9]|22[0-5])$"
+            - enum: [ ufs_reset, sdc2_clk, sdc2_cmd, sdc2_data ]
+        minItems: 1
+        maxItems: 36
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+        enum: [ gpio, aoss_cti, atest_char, atest_usb, audio_ext_mclk,
+                audio_ref_clk, cam_mclk, cci_async_in, cci_i2c0, cci_i2c1,
+                cci_i2c2, cci_i2c3, cci_i2c4, cci_i2c5, cci_timer, coex_espmi,
+                coex_uart1_rx, coex_uart1_tx, dbg_out_clk, ddr_bist, ddr_pxi,
+                dp_hot, egpio, gcc_gp, gnss_adc, host_rst, i2chub0_se0,
+                i2chub0_se1, i2chub0_se2, i2chub0_se3, i2chub0_se4, i2s0, i2s1,
+                ibi_i3c, jitter_bist, mdp_esync0, mdp_esync1, mdp_esync2,
+                mdp_vsync, mdp_vsync_e, mdp_vsync_p, mdp_vsync0_out,
+                mdp_vsync1_out, mdp_vsync2_out, mdp_vsync3_out, mdp_vsync5_out,
+                modem_pps_in, modem_pps_out, nav_gpio, nav_gpio0, nav_gpio3,
+                nav_rffe, pcie0_clk_req_n, pcie0_rst_n, pcie1_clk_req_n,
+                phase_flag, pll_bist_sync, pll_clk_aux, qdss_cti, qlink,
+                qspi, qspi_clk, qspi_cs, qup1_se0, qup1_se1, qup1_se2,
+                qup1_se3, qup1_se4, qup1_se5, qup1_se6, qup1_se7, qup2_se0,
+                qup2_se1, qup2_se2, qup2_se3, qup2_se4_01, qup2_se4_23,
+                qup3_se0_01, qup3_se0_23, qup3_se1, qup3_se2, qup3_se3,
+                qup3_se4, qup3_se5, qup4_se0, qup4_se1, qup4_se2, qup4_se3_01,
+                qup4_se3_23, qup4_se3_l3, qup4_se4_01, qup4_se4_23, qup4_se4_l3,
+                rng_rosc, sd_write_protect, sdc4_clk, sdc4_cmd, sdc4_data,
+                sys_throttle, tb_trig_sdc, tmess_rng, tsense_clm, tsense_pwm,
+                uim0, uim1, usb0_hs, usb_phy, vfr, vsense_trigger_mirnat,
+                wcn_sw_ctrl ]
+
+    required:
+      - pins
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tlmm: pinctrl@f100000 {
+        compatible = "qcom,hawi-tlmm";
+        reg = <0x0f100000 0x300000>;
+        interrupts = <GIC_ESPI 272 IRQ_TYPE_LEVEL_HIGH>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&tlmm 0 0 227>;
+        interrupt-controller;
+        #interrupt-cells = <2>;
+
+        qup-uart7-state {
+          pins = "gpio62", "gpio63";
+          function = "qup1_se7";
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,ipq5210-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5210-tlmm.yaml
new file mode 100644
index 0000000..12c5e76
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,ipq5210-tlmm.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,ipq5210-tlmm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm IPQ5210 TLMM pin controller
+
+maintainers:
+  - Bjorn Andersson <andersson@kernel.org>
+  - Kathiravan Thirumoorthy <kathiravan.thirumoorthy@oss.qualcomm.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in Qualcomm IPQ5210 SoC.
+
+allOf:
+  - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml#
+
+properties:
+  compatible:
+    const: qcom,ipq5210-tlmm
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 27
+
+  gpio-line-names:
+    maxItems: 54
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-ipq5210-tlmm-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-ipq5210-tlmm-state"
+        additionalProperties: false
+
+$defs:
+  qcom-ipq5210-tlmm-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,tlmm-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          pattern: "^gpio([0-9]|[1-4][0-9]|5[0-3])$"
+        minItems: 1
+        maxItems: 36
+
+      function:
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+
+        enum: [ atest_char_start, atest_char_status0, atest_char_status1,
+                atest_char_status2, atest_char_status3, atest_tic_en, audio_pri,
+                audio_pri_mclk_out0, audio_pri_mclk_in0, audio_pri_mclk_out1,
+                audio_pri_mclk_in1, audio_pri_mclk_out2, audio_pri_mclk_in2,
+                audio_pri_mclk_out3, audio_pri_mclk_in3, audio_sec,
+                audio_sec_mclk_out0, audio_sec_mclk_in0, audio_sec_mclk_out1,
+                audio_sec_mclk_in1, audio_sec_mclk_out2, audio_sec_mclk_in2,
+                audio_sec_mclk_out3, audio_sec_mclk_in3, core_voltage_0,
+                cri_trng0, cri_trng1, cri_trng2, cri_trng3, dbg_out_clk, dg_out,
+                gcc_plltest_bypassnl, gcc_plltest_resetn, gcc_tlmm, gpio, led0,
+                led1, led2, mdc_mst, mdc_slv0, mdc_slv1, mdc_slv2, mdio_mst,
+                mdio_slv0, mdio_slv1, mdio_slv2, mux_tod_out, pcie0_clk_req_n,
+                pcie0_wake, pcie1_clk_req_n, pcie1_wake, pll_test,
+                pon_active_led, pon_mux_sel, pon_rx, pon_rx_los, pon_tx,
+                pon_tx_burst, pon_tx_dis, pon_tx_fault, pon_tx_sd, gpn_rx_los,
+                gpn_tx_burst, gpn_tx_dis, gpn_tx_fault, gpn_tx_sd, pps, pwm0,
+                pwm1, pwm2, pwm3, qdss_cti_trig_in_a0, qdss_cti_trig_in_a1,
+                qdss_cti_trig_in_b0, qdss_cti_trig_in_b1, qdss_cti_trig_out_a0,
+                qdss_cti_trig_out_a1, qdss_cti_trig_out_b0,
+                qdss_cti_trig_out_b1, qdss_traceclk_a, qdss_tracectl_a,
+                qdss_tracedata_a, qrng_rosc0, qrng_rosc1, qrng_rosc2,
+                qspi_data, qspi_clk, qspi_cs_n, qup_se0, qup_se1, qup_se2,
+                qup_se3, qup_se4, qup_se5, qup_se5_l1, resout, rx_los0, rx_los1,
+                rx_los2, sdc_clk, sdc_cmd, sdc_data, tsens_max ]
+
+    required:
+      - pins
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    tlmm: pinctrl@1000000 {
+        compatible = "qcom,ipq5210-tlmm";
+        reg = <0x01000000 0x300000>;
+        gpio-controller;
+        #gpio-cells = <0x2>;
+        gpio-ranges = <&tlmm 0 0 54>;
+        interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-controller;
+        #interrupt-cells = <0x2>;
+
+        qup-uart1-default-state {
+            pins = "gpio38", "gpio39";
+            function = "qup_se1";
+            drive-strength = <6>;
+            bias-pull-down;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml
index 619341d..30f93b8 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,lpass-lpi-common.yaml
@@ -27,6 +27,14 @@
   gpio-ranges:
     maxItems: 1
 
+  gpio-reserved-ranges:
+    minItems: 1
+    maxItems: 30
+    description:
+      Pins can be reserved for trusted applications or for LPASS, thereby
+      inaccessible from the OS. This property can be used to mark the pins
+      which resources should not be accessed by the OS.
+
 required:
   - gpio-controller
   - "#gpio-cells"
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml
new file mode 100644
index 0000000..73e84f1
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,milos-lpass-lpi-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Milos SoC LPASS LPI TLMM
+
+maintainers:
+  - Luca Weiss <luca.weiss@fairphone.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in the Low Power Audio SubSystem
+  (LPASS) Low Power Island (LPI) of Qualcomm Milos SoC.
+
+properties:
+  compatible:
+    const: qcom,milos-lpass-lpi-pinctrl
+
+  reg:
+    items:
+      - description: LPASS LPI TLMM Control and Status registers
+      - description: LPASS LPI MCC registers
+
+  clocks:
+    items:
+      - description: LPASS Core voting clock
+      - description: LPASS Audio voting clock
+
+  clock-names:
+    items:
+      - const: core
+      - const: audio
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-milos-lpass-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-milos-lpass-state"
+        additionalProperties: false
+
+$defs:
+  qcom-milos-lpass-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          pattern: "^gpio([0-9]|1[0-9]|2[0-2])$"
+
+      function:
+        enum: [ dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic3_clk,
+                dmic3_data, dmic4_clk, dmic4_data, ext_mclk1_a, ext_mclk1_b,
+                ext_mclk1_c, ext_mclk1_d, ext_mclk1_e, gpio, i2s0_clk,
+                i2s0_data, i2s0_ws, i2s1_clk, i2s1_data, i2s1_ws, i2s2_clk,
+                i2s2_data, i2s2_ws, i2s3_clk, i2s3_data, i2s3_ws, qca_swr_clk,
+                qca_swr_data, slimbus_clk, slimbus_data, swr_rx_clk,
+                swr_rx_data, swr_tx_clk, swr_tx_data, wsa_swr_clk,
+                wsa_swr_data ]
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+
+allOf:
+  - $ref: qcom,lpass-lpi-common.yaml#
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+
+    pinctrl@3440000 {
+        compatible = "qcom,milos-lpass-lpi-pinctrl";
+        reg = <0x03440000 0x20000>,
+              <0x034d0000 0x10000>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&lpass_tlmm 0 0 23>;
+
+        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";
+
+        tx-swr-active-clk-state {
+            pins = "gpio0";
+            function = "swr_tx_clk";
+            drive-strength = <4>;
+            slew-rate = <1>;
+            bias-disable;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-lpass-lpi-pinctrl.yaml
new file mode 100644
index 0000000..c76ad70
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sdm670-lpass-lpi-pinctrl.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,sdm670-lpass-lpi-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SDM670 SoC LPASS LPI TLMM
+
+maintainers:
+  - Richard Acayan <mailingradian@gmail.com>
+
+description:
+  Top Level Mode Multiplexer pin controller in the Low Power Audio SubSystem
+  (LPASS) Low Power Island (LPI) of Qualcomm SDM670 SoC.
+
+properties:
+  compatible:
+    const: qcom,sdm670-lpass-lpi-pinctrl
+
+  reg:
+    items:
+      - description: LPASS LPI TLMM Control and Status registers
+
+patternProperties:
+  "-state$":
+    oneOf:
+      - $ref: "#/$defs/qcom-sdm670-lpass-state"
+      - patternProperties:
+          "-pins$":
+            $ref: "#/$defs/qcom-sdm670-lpass-state"
+        additionalProperties: false
+
+$defs:
+  qcom-sdm670-lpass-state:
+    type: object
+    description:
+      Pinctrl node's client devices use subnodes for desired pin configuration.
+      Client device subnodes use below standard properties.
+    $ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
+    unevaluatedProperties: false
+
+    properties:
+      pins:
+        description:
+          List of gpio pins affected by the properties specified in this
+          subnode.
+        items:
+          pattern: "^gpio([0-9]|1[0-9]|2[0-9]|3[0-1])$"
+
+      function:
+        enum: [ gpio, comp_rx, dmic1_clk, dmic1_data, dmic2_clk, dmic2_data,
+                i2s1_clk, i2s_data, i2s_ws, lpi_cdc_rst, mclk0, pdm_rx,
+                pdm_sync, pdm_tx, slimbus_clk ]
+        description:
+          Specify the alternative function to be configured for the specified
+          pins.
+
+allOf:
+  - $ref: qcom,lpass-lpi-common.yaml#
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    lpi_tlmm: pinctrl@62b40000 {
+        compatible = "qcom,sdm670-lpass-lpi-pinctrl";
+        reg = <0x62b40000 0x20000>;
+        gpio-controller;
+        #gpio-cells = <2>;
+        gpio-ranges = <&lpi_tlmm 0 0 32>;
+
+        cdc_comp_default: cdc-comp-default-state {
+            pins = "gpio22", "gpio24";
+            function = "comp_rx";
+            drive-strength = <4>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml
index e756559..541c1c5 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8450-lpass-lpi-pinctrl.yaml
@@ -15,7 +15,13 @@
 
 properties:
   compatible:
-    const: qcom,sm8450-lpass-lpi-pinctrl
+    oneOf:
+      - const: qcom,sm8450-lpass-lpi-pinctrl
+      - items:
+          - enum:
+              - qcom,qcs8300-lpass-lpi-pinctrl
+              - qcom,sa8775p-lpass-lpi-pinctrl
+          - const: qcom,sm8450-lpass-lpi-pinctrl
 
   reg:
     items:
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml
index 74df912..1bf0886 100644
--- a/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm8650-lpass-lpi-pinctrl.yaml
@@ -19,7 +19,9 @@
     oneOf:
       - const: qcom,sm8650-lpass-lpi-pinctrl
       - items:
-          - const: qcom,sm8750-lpass-lpi-pinctrl
+          - enum:
+              - qcom,glymur-lpass-lpi-pinctrl
+              - qcom,sm8750-lpass-lpi-pinctrl
           - const: qcom,sm8650-lpass-lpi-pinctrl
 
   reg:
diff --git a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1315e-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1315e-pinctrl.yaml
index 90bd49d..2a640e4 100644
--- a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1315e-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1315e-pinctrl.yaml
@@ -135,8 +135,11 @@
 
       realtek,duty-cycle:
         description: |
-          An integer describing the level to adjust output duty cycle, controlling
-          the proportion of positive and negative waveforms in nanoseconds.
+          An integer describing the level to adjust the output pulse width, it
+          provides a fixed nanosecond-level adjustment to the rising/falling
+          edges of an existing signal. It is used for Signal Integrity tuning
+          (adding/subtracting delay to fine-tune the high/low duration), rather
+          than generating a specific PWM frequency.
           Valid arguments are described as below:
           0: 0ns
           2: + 0.25ns
diff --git a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1319d-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1319d-pinctrl.yaml
index b6211c8..2136546 100644
--- a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1319d-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1319d-pinctrl.yaml
@@ -134,8 +134,11 @@
 
       realtek,duty-cycle:
         description: |
-          An integer describing the level to adjust output duty cycle, controlling
-          the proportion of positive and negative waveforms in nanoseconds.
+          An integer describing the level to adjust the output pulse width, it
+          provides a fixed nanosecond-level adjustment to the rising/falling
+          edges of an existing signal. It is used for Signal Integrity tuning
+          (adding/subtracting delay to fine-tune the high/low duration), rather
+          than generating a specific PWM frequency.
           Valid arguments are described as below:
           0: 0ns
           2: + 0.25ns
diff --git a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1619b-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1619b-pinctrl.yaml
index e88bc64..e8ea136 100644
--- a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1619b-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1619b-pinctrl.yaml
@@ -133,8 +133,11 @@
 
       realtek,duty-cycle:
         description: |
-          An integer describing the level to adjust output duty cycle, controlling
-          the proportion of positive and negative waveforms in nanoseconds.
+          An integer describing the level to adjust the output pulse width, it
+          provides a fixed nanosecond-level adjustment to the rising/falling
+          edges of an existing signal. It is used for Signal Integrity tuning
+          (adding/subtracting delay to fine-tune the high/low duration), rather
+          than generating a specific PWM frequency.
           Valid arguments are described as below:
           0: 0ns
           2: + 0.25ns
diff --git a/Documentation/devicetree/bindings/pinctrl/realtek,rtd1625-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1625-pinctrl.yaml
new file mode 100644
index 0000000..9562a04
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/realtek,rtd1625-pinctrl.yaml
@@ -0,0 +1,260 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2025 Realtek Semiconductor Corporation
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/realtek,rtd1625-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek DHC RTD1625 Pin Controller
+
+maintainers:
+  - Tzuyi Chang <tychang@realtek.com>
+  - Yu-Chun Lin <eleanor.lin@realtek.com>
+
+description:
+  The Realtek DHC RTD1625 is a high-definition media processor SoC. The
+  RTD1625 pin controller is used to control pin function, pull-up/down
+  resistors, drive strength, slew rate, Schmitt trigger, power source
+  (I/O output voltage), input threshold domain selection and a higher-VIL mode.
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - realtek,rtd1625-iso-pinctrl
+          - realtek,rtd1625-main2-pinctrl
+          - realtek,rtd1625-isom-pinctrl
+          - realtek,rtd1625-ve4-pinctrl
+
+  reg:
+    maxItems: 1
+
+patternProperties:
+  '-pins$':
+    type: object
+    allOf:
+      - $ref: pincfg-node.yaml#
+      - $ref: pinmux-node.yaml#
+
+    properties:
+      pins:
+        items:
+          enum: [gpio_0, gpio_1, gpio_2, gpio_3, gpio_4, gpio_5, gpio_6,
+                 gpio_7, gpio_8, gpio_9, gpio_10, gpio_11, gpio_12, gpio_13,
+                 gpio_14, gpio_15, gpio_16, gpio_17, gpio_18, gpio_19, gpio_20,
+                 gpio_21, gpio_22, gpio_23, gpio_24, gpio_25, gpio_28, gpio_29,
+                 gpio_30, gpio_31, gpio_32, gpio_33, gpio_34, gpio_35, gpio_40,
+                 gpio_41, gpio_42, gpio_43, gpio_44, gpio_45, gpio_46, gpio_47,
+                 gpio_48, gpio_49, gpio_50, gpio_51, gpio_52, gpio_53, gpio_54,
+                 gpio_55, gpio_56, gpio_57, gpio_58, gpio_59, gpio_60, gpio_61,
+                 gpio_62, gpio_63, gpio_64, gpio_65, gpio_66, gpio_67, gpio_80,
+                 gpio_81, gpio_82, gpio_83, gpio_84, gpio_85, gpio_86, gpio_87,
+                 gpio_88, gpio_89, gpio_90, gpio_91, gpio_92, gpio_93, gpio_94,
+                 gpio_95, gpio_96, gpio_97, gpio_98, gpio_99, gpio_100,
+                 gpio_101, gpio_102, gpio_103, gpio_104, gpio_105, gpio_106,
+                 gpio_107, gpio_108, gpio_109, gpio_110, gpio_111, gpio_112,
+                 gpio_128, gpio_129, gpio_130, gpio_131, gpio_132, gpio_133,
+                 gpio_134, gpio_135, gpio_136, gpio_137, gpio_138, gpio_139,
+                 gpio_140, gpio_141, gpio_142, gpio_143, gpio_144, gpio_145,
+                 gpio_146, gpio_147, gpio_148, gpio_149, gpio_150, gpio_151,
+                 gpio_152, gpio_153, gpio_154, gpio_155, gpio_156, gpio_157,
+                 gpio_158, gpio_159, gpio_160, gpio_161, gpio_162, gpio_163,
+                 gpio_164, gpio_165, ai_i2s1_loc, ao_i2s1_loc, arm_trace_dbg_en,
+                 csi_vdsel, ejtag_acpu_loc, ejtag_aucpu0_loc, ejtag_aucpu1_loc,
+                 ejtag_pcpu_loc, ejtag_scpu_loc, ejtag_ve2_loc, emmc_clk,
+                 emmc_cmd, emmc_data_0, emmc_data_1, emmc_data_2, emmc_data_3,
+                 emmc_data_4, emmc_data_5, emmc_data_6, emmc_data_7,
+                 emmc_dd_sb, emmc_rst_n, etn_phy_loc, hif_clk, hif_data,
+                 hif_en, hif_rdy, hi_width, i2c6_loc, ir_rx_loc, rgmii_vdsel,
+                 sf_en, spdif_in_mode, spdif_loc, uart0_loc, usb_cc1, usb_cc2,
+                 ve4_uart_loc]
+
+      function:
+        enum: [gpio, ai_i2s0, ai_i2s2, ai_tdm0, ai_tdm1, ai_tdm2, ao_i2s0,
+               ao_i2s2, ao_tdm0, ao_tdm1, ao_tdm2, csi0, csi1, csi_1v2, csi_1v8,
+               csi_2v5, csi_3v3, dmic0, dmic1, dmic2, dptx_hpd, edptx_hdp, emmc,
+               gspi0, gspi1, gspi2, hi_width_1bit, hi_width_disable, i2c0, i2c1,
+               i2c3, i2c4, i2c5, i2c7, iso_tristate, pcie0, pcie1, pcm, pctrl,
+               pwm4, pwm5, pwm6, rgmii, rgmii_1v2, rgmii_1v8, rgmii_2v5,
+               rgmii_3v3, rmii, sd, sdio, sf_disable, sf_enable,
+               spdif_in_coaxial, spdif_in_gpio, spdif_out, spi, ts0, ts1, uart1,
+               uart2, uart3, uart4, uart5, uart6, uart7, uart8, uart9, uart10,
+               usb_cc1, usb_cc2, vi0_dtv, vi1_dtv, vtc_ao_i2s, vtc_dmic,
+               vtc_i2s, ai_i2s1_loc0, ai_i2s1_loc1, ao_i2s0_loc0, ao_i2s0_loc1,
+               ao_i2s1_loc0, ao_i2s1_loc1, ao_tdm1_loc0, ao_tdm1_loc1,
+               etn_led_loc0, etn_led_loc1, etn_phy_loc0, etn_phy_loc1,
+               i2c6_loc0, i2c6_loc1, ir_rx_loc0, ir_rx_loc1, pwm0_loc0,
+               pwm0_loc1, pwm0_loc2, pwm0_loc3, pwm1_loc0, pwm1_loc1, pwm2_loc0,
+               pwm2_loc1, pwm3_loc0, pwm3_loc1, spdif_loc0, spdif_loc1,
+               uart0_loc0, uart0_loc1, ve4_uart_loc0, ve4_uart_loc1,
+               ve4_uart_loc2, acpu_ejtag_loc0, acpu_ejtag_loc1, acpu_ejtag_loc2,
+               aucpu0_ejtag_loc0, aucpu0_ejtag_loc1, aucpu0_ejtag_loc2,
+               aucpu1_ejtag_loc0, aucpu1_ejtag_loc1, aucpu1_ejtag_loc2,
+               aupu0_ejtag_loc1, aupu1_ejtag_loc1, gpu_ejtag_loc0,
+               pcpu_ejtag_loc0, pcpu_ejtag_loc1, pcpu_ejtag_loc2,
+               scpu_ejtag_loc0, scpu_ejtag_loc1, scpu_ejtag_loc2,
+               ve2_ejtag_loc0, ve2_ejtag_loc1, ve2_ejtag_loc2, pll_test_loc0,
+               pll_test_loc1, dbg_out1, isom_dbg_out, arm_trace_debug_disable,
+               arm_trace_debug_enable]
+
+      drive-strength:
+        enum: [4, 8]
+
+      bias-pull-down: true
+
+      bias-pull-up: true
+
+      bias-disable: true
+
+      input-schmitt-enable: true
+
+      input-schmitt-disable: true
+
+      input-voltage-microvolt:
+        description: |
+          Select the input receiver voltage domain for the pin.
+          Valid arguments are:
+          - 1800000: 1.8V input logic level
+          - 3300000: 3.3V input logic level
+        enum: [1800000, 3300000]
+
+      drive-push-pull: true
+
+      power-source:
+        description: |
+          Valid arguments are described as below:
+          0: power supply of 1.8V
+          1: power supply of 3.3V
+        enum: [0, 1]
+
+      slew-rate:
+        description: |
+          Valid arguments are described as below:
+            1: ~1ns falling time
+            10: ~10ns falling time
+            20: ~20ns falling time
+            30: ~30ns falling time
+        enum: [1, 10, 20, 30]
+
+      realtek,drive-strength-p:
+        description: |
+          Some of pins can be driven using the P-MOS and N-MOS transistor to
+          achieve finer adjustments. The block-diagram representation is as
+          follows:
+                         VDD
+                          |
+                      ||--+
+               +-----o||     P-MOS-FET
+               |      ||--+
+          IN --+          +----- out
+               |      ||--+
+               +------||     N-MOS-FET
+                      ||--+
+                          |
+                         GND
+          The driving strength of the P-MOS/N-MOS transistors impacts the
+          waveform's rise/fall times. Greater driving strength results in
+          shorter rise/fall times. Each P-MOS and N-MOS transistor offers
+          8 configurable levels (0 to 7), with higher values indicating
+          greater driving strength, contributing to achieving the desired
+          speed.
+
+          The realtek,drive-strength-p is used to control the driving strength
+          of the P-MOS output.
+
+          This value is not a simple count of transistors. Instead, it
+          represents a weighted configuration. There is a base driving
+          capability (even at value 0), and each bit adds a different weight to
+          the total strength. The resulting current is non-linear and varies
+          significantly based on the IO voltage (1.8V vs 3.3V) and the specific
+          pad group.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 0
+        maximum: 7
+
+      realtek,drive-strength-n:
+        description: |
+          Similar to the realtek,drive-strength-p, the realtek,drive-strength-n
+          is used to control the driving strength of the N-MOS output.
+
+          This property uses the same weighted configuration logic where values
+          0-7 represent non-linear strength adjustments rather than a transistor
+          count.
+
+          Higher values indicate greater driving strength, resulting in shorter
+          fall times.
+        $ref: /schemas/types.yaml#/definitions/uint32
+        minimum: 0
+        maximum: 7
+
+      realtek,duty-cycle:
+        description: |
+          An integer describing the level to adjust the output pulse width, it
+          provides a fixed nanosecond-level adjustment to the rising/falling
+          edges of an existing signal. It is used for Signal Integrity tuning
+          (adding/subtracting delay to fine-tune the high/low duration), rather
+          than generating a specific PWM frequency.
+
+          Valid arguments are described as below:
+          0: 0ns
+          2: + 0.25ns
+          3: + 0.5ns
+          4: -0.25ns
+          5: -0.5ns
+        $ref: /schemas/types.yaml#/definitions/uint32
+        enum: [0, 2, 3, 4, 5]
+
+      realtek,high-vil-microvolt:
+        description: |
+          The threshold value for the input receiver's LOW recognition (VIL).
+
+          This property is used to address specific HDMI I2C compatibility
+          issues where some sinks (TVs) have weak pull-down capabilities and
+          fail to pull the bus voltage below the standard VIL threshold
+          (~0.7V).
+
+          Setting this property to 1100000 (1.1V) enables a specialized input
+          receiver mode that raises the effective VIL threshold to improve
+          detection.
+        enum: [1100000]
+
+    required:
+      - pins
+
+    additionalProperties: false
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    pinctrl@4e000 {
+        compatible = "realtek,rtd1625-iso-pinctrl";
+        reg = <0x4e000 0x130>;
+
+        emmc-hs200-pins {
+            pins = "emmc_clk",
+                   "emmc_cmd",
+                   "emmc_data_0",
+                   "emmc_data_1",
+                   "emmc_data_2",
+                   "emmc_data_3",
+                   "emmc_data_4",
+                   "emmc_data_5",
+                   "emmc_data_6",
+                   "emmc_data_7";
+            function = "emmc";
+            realtek,drive-strength-p = <2>;
+            realtek,drive-strength-n = <2>;
+        };
+
+        i2c-0-pins {
+            pins = "gpio_12",
+                   "gpio_13";
+            function = "i2c0";
+            drive-strength = <4>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml
index f049013..63993b2 100644
--- a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml
@@ -83,6 +83,23 @@
       input: true
       input-enable: true
       output-enable: true
+      bias-disable: true
+      bias-pull-down: true
+      bias-pull-up: true
+      input-schmitt-enable: true
+      input-schmitt-disable: true
+      slew-rate:
+        description: 0 is slow slew rate, 1 is fast slew rate
+        enum: [0, 1]
+      drive-strength-microamp:
+        description: |
+          Four discrete levels are supported (via registers DRCTLm), corresponding
+          to the following nominal values:
+          - 2500  (Low strength)
+          - 5000  (Middle strength)
+          - 9000  (High strength)
+          - 11800 (Ultra High strength)
+        enum: [2500, 5000, 9000, 11800]
     oneOf:
       - required: [pinmux]
       - required: [pins]
diff --git a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
index 76e6072..9b3cbeb 100644
--- a/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
+++ b/Documentation/devicetree/bindings/pinctrl/rockchip,pinctrl.yaml
@@ -50,6 +50,7 @@
       - rockchip,rk3568-pinctrl
       - rockchip,rk3576-pinctrl
       - rockchip,rk3588-pinctrl
+      - rockchip,rv1103b-pinctrl
       - rockchip,rv1108-pinctrl
       - rockchip,rv1126-pinctrl
 
diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
index 04519b0..d8f4f9f 100644
--- a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
+++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -8,7 +8,7 @@
 
 maintainers:
   - asahi@lists.linux.dev
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description: PWM controller used for keyboard backlight on ARM Macs
 
diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml
index e9e07c2..bb7b9c8 100644
--- a/Documentation/devicetree/bindings/serial/8250.yaml
+++ b/Documentation/devicetree/bindings/serial/8250.yaml
@@ -182,6 +182,7 @@
           - const: ns16550a
       - items:
           - enum:
+              - loongson,ls3a4000-uart
               - loongson,ls3a5000-uart
               - loongson,ls3a6000-uart
               - loongson,ls2k2000-uart
diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
index d8ad1bb..a270231 100644
--- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
@@ -56,6 +56,7 @@
         items:
           - enum:
               - amlogic,a4-uart
+              - amlogic,a9-uart
               - amlogic,s6-uart
               - amlogic,s7-uart
               - amlogic,s7d-uart
diff --git a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
index 087a892..375cd50 100644
--- a/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
+++ b/Documentation/devicetree/bindings/serial/atmel,at91-usart.yaml
@@ -24,6 +24,7 @@
           - const: atmel,at91sam9260-usart
       - items:
           - enum:
+              - microchip,lan9691-usart
               - microchip,sam9x60-usart
               - microchip,sam9x7-usart
               - microchip,sama7d65-usart
diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
index e059b14..85ebb30 100644
--- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
+++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml
@@ -14,6 +14,7 @@
   compatible:
     oneOf:
       - enum:
+          - renesas,r9a08g046-rsci # RZ/G3L
           - renesas,r9a09g047-rsci # RZ/G3E
           - renesas,r9a09g077-rsci # RZ/T2H
 
@@ -145,6 +146,31 @@
         - resets
         - reset-names
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: renesas,r9a08g046-rsci
+    then:
+      properties:
+        interrupts:
+          minItems: 6
+
+        interrupt-names:
+          minItems: 6
+
+        clocks:
+          minItems: 2
+          maxItems: 3
+
+        clock-names:
+          minItems: 2
+          maxItems: 3
+
+      required:
+        - resets
+        - reset-names
+
 unevaluatedProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index 6efe430..685c1ec 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -71,6 +71,7 @@
               - rockchip,rk3568-uart
               - rockchip,rk3576-uart
               - rockchip,rk3588-uart
+              - rockchip,rv1103b-uart
               - rockchip,rv1108-uart
               - rockchip,rv1126-uart
               - sophgo,sg2044-uart
diff --git a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml
index f3a5638..b21466b 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas2781.yaml
+++ b/Documentation/devicetree/bindings/sound/ti,tas2781.yaml
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-# Copyright (C) 2022 - 2025 Texas Instruments Incorporated
+# Copyright (C) 2022 - 2026 Texas Instruments Incorporated
 %YAML 1.2
 ---
 $id: http://devicetree.org/schemas/sound/ti,tas2781.yaml#
@@ -107,6 +107,9 @@
 
       ti,tas5830: 65-W Stereo, Digital Input, High Efficiency Closed-Loop
       Class-D Amplifier with Class-H Algorithm
+
+      ti,tas5832: 81-W Stereo, Digital Input, High Efficiency Closed-Loop
+      Class-D Amplifier with Class-H Algorithm
     oneOf:
       - items:
           - enum:
@@ -128,6 +131,7 @@
               - ti,tas5827
               - ti,tas5828
               - ti,tas5830
+              - ti,tas5832
           - const: ti,tas2781
       - enum:
           - ti,tas2781
@@ -264,6 +268,7 @@
               - ti,tas5827
               - ti,tas5828
               - ti,tas5830
+              - ti,tas5832
     then:
       properties:
         reg:
diff --git a/Documentation/devicetree/bindings/spi/fsl,spi.yaml b/Documentation/devicetree/bindings/spi/fsl,spi.yaml
index d74792f..6a35948 100644
--- a/Documentation/devicetree/bindings/spi/fsl,spi.yaml
+++ b/Documentation/devicetree/bindings/spi/fsl,spi.yaml
@@ -59,7 +59,7 @@
 
 examples:
   - |
-    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/gpio/gpio.h>
 
     spi@4c0 {
         compatible = "fsl,spi";
@@ -67,8 +67,8 @@
         cell-index = <0>;
         interrupts = <82 0>;
         mode = "cpu";
-        cs-gpios = <&gpio 18 IRQ_TYPE_EDGE_RISING          // device reg=<0>
-                    &gpio 19 IRQ_TYPE_EDGE_RISING>;        // device reg=<1>
+        cs-gpios = <&gpio 18 GPIO_ACTIVE_HIGH>,        // device reg=<0>
+                   <&gpio 19 GPIO_ACTIVE_HIGH>;        // device reg=<1>
     };
 
 ...
diff --git a/Documentation/devicetree/bindings/spmi/apple,spmi.yaml b/Documentation/devicetree/bindings/spmi/apple,spmi.yaml
index ba524f1..3e5b14b 100644
--- a/Documentation/devicetree/bindings/spmi/apple,spmi.yaml
+++ b/Documentation/devicetree/bindings/spmi/apple,spmi.yaml
@@ -7,7 +7,7 @@
 title: Apple SPMI controller
 
 maintainers:
-  - Sasha Finkelstein <fnkl.kernel@gmail.com>
+  - Sasha Finkelstein <k@chaosmail.tech>
 
 description: A SPMI controller present on most Apple SoCs
 
diff --git a/Documentation/devicetree/bindings/thermal/max77620_thermal.txt b/Documentation/devicetree/bindings/thermal/max77620_thermal.txt
deleted file mode 100644
index 82ed5d4..0000000
--- a/Documentation/devicetree/bindings/thermal/max77620_thermal.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-Thermal driver for MAX77620 Power management IC from Maxim Semiconductor.
-
-Maxim Semiconductor MAX77620 supports alarm interrupts when its
-die temperature crosses 120C and 140C. These threshold temperatures
-are not configurable. Device does not provide the real temperature
-of die other than just indicating whether temperature is above or
-below threshold level.
-
-Required properties:
--------------------
-#thermal-sensor-cells:	For more details, please refer to
-			<devicetree/bindings/thermal/thermal-sensor.yaml>
-			The value must be 0.
-
-For more details, please refer generic thermal DT binding document
-<devicetree/bindings/thermal/thermal*.yaml>.
-
-Please refer <devicetree/bindings/mfd/max77620.txt> for mfd DT binding
-document for the MAX77620.
-
-Example:
---------
-#include <dt-bindings/mfd/max77620.h>
-#include <dt-bindings/thermal/thermal.h>
-...
-
-i2c@7000d000 {
-	spmic: max77620@3c {
-		compatible = "maxim,max77620";
-		:::::
-		#thermal-sensor-cells = <0>;
-		:::
-	};
-};
-
-cool_dev: cool-dev {
-	compatible = "cooling-dev";
-	#cooling-cells = <2>;
-};
-
-thermal-zones {
-	PMIC-Die {
-		polling-delay = <0>;
-		polling-delay-passive = <0>;
-		thermal-sensors = <&spmic>;
-
-		trips {
-			pmic_die_warn_temp_thresh: hot-die {
-				temperature = <120000>;
-				type = "hot";
-				hysteresis = <0>;
-			};
-
-			pmic_die_cirt_temp_thresh: cirtical-die {
-				temperature = <140000>;
-				type = "critical";
-				hysteresis = <0>;
-			};
-		};
-
-		cooling-maps {
-			map0 {
-				trip = <&pmic_die_warn_temp_thresh>;
-				cooling-device = <&cool_dev THERMAL_NO_LIMIT
-						  THERMAL_NO_LIMIT>;
-				contribution = <100>;
-			};
-		};
-	};
-};
diff --git a/Documentation/devicetree/bindings/ufs/qcom,sc7180-ufshc.yaml b/Documentation/devicetree/bindings/ufs/qcom,sc7180-ufshc.yaml
index d94ef4e..3c40742 100644
--- a/Documentation/devicetree/bindings/ufs/qcom,sc7180-ufshc.yaml
+++ b/Documentation/devicetree/bindings/ufs/qcom,sc7180-ufshc.yaml
@@ -15,6 +15,7 @@
     compatible:
       contains:
         enum:
+          - qcom,milos-ufshc
           - qcom,msm8998-ufshc
           - qcom,qcs8300-ufshc
           - qcom,sa8775p-ufshc
@@ -31,21 +32,28 @@
 
 properties:
   compatible:
-    items:
-      - enum:
-          - qcom,msm8998-ufshc
-          - qcom,qcs8300-ufshc
-          - qcom,sa8775p-ufshc
-          - qcom,sc7180-ufshc
-          - qcom,sc7280-ufshc
-          - qcom,sc8180x-ufshc
-          - qcom,sc8280xp-ufshc
-          - qcom,sm8250-ufshc
-          - qcom,sm8350-ufshc
-          - qcom,sm8450-ufshc
-          - qcom,sm8550-ufshc
-      - const: qcom,ufshc
-      - const: jedec,ufs-2.0
+    oneOf:
+      - items:
+          - enum:
+              - qcom,x1e80100-ufshc
+          - const: qcom,sm8550-ufshc
+          - const: qcom,ufshc
+      - items:
+          - enum:
+              - qcom,milos-ufshc
+              - qcom,msm8998-ufshc
+              - qcom,qcs8300-ufshc
+              - qcom,sa8775p-ufshc
+              - qcom,sc7180-ufshc
+              - qcom,sc7280-ufshc
+              - qcom,sc8180x-ufshc
+              - qcom,sc8280xp-ufshc
+              - qcom,sm8250-ufshc
+              - qcom,sm8350-ufshc
+              - qcom,sm8450-ufshc
+              - qcom,sm8550-ufshc
+          - const: qcom,ufshc
+          - const: jedec,ufs-2.0
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
index cea84ab..f28641c 100644
--- a/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
+++ b/Documentation/devicetree/bindings/ufs/qcom,sm8650-ufshc.yaml
@@ -15,6 +15,7 @@
     compatible:
       contains:
         enum:
+          - qcom,eliza-ufshc
           - qcom,kaanapali-ufshc
           - qcom,sm8650-ufshc
           - qcom,sm8750-ufshc
@@ -25,6 +26,7 @@
   compatible:
     items:
       - enum:
+          - qcom,eliza-ufshc
           - qcom,kaanapali-ufshc
           - qcom,sm8650-ufshc
           - qcom,sm8750-ufshc
@@ -66,6 +68,18 @@
 
 allOf:
   - $ref: qcom,ufs-common.yaml
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - qcom,eliza-ufshc
+    then:
+      properties:
+        reg:
+          minItems: 2
+        reg-names:
+          minItems: 2
 
 unevaluatedProperties: false
 
diff --git a/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
index c7d17cf4..e738153 100644
--- a/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
+++ b/Documentation/devicetree/bindings/ufs/rockchip,rk3576-ufshc.yaml
@@ -41,7 +41,7 @@
     maxItems: 1
 
   resets:
-    maxItems: 4
+    maxItems: 5
 
   reset-names:
     items:
@@ -49,6 +49,7 @@
       - const: sys
       - const: ufs
       - const: grf
+      - const: mphy
 
   reset-gpios:
     maxItems: 1
@@ -98,8 +99,8 @@
             interrupts = <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>;
             power-domains = <&power RK3576_PD_USB>;
             resets = <&cru SRST_A_UFS_BIU>, <&cru SRST_A_UFS_SYS>, <&cru SRST_A_UFS>,
-                     <&cru SRST_P_UFS_GRF>;
-            reset-names = "biu", "sys", "ufs", "grf";
+                     <&cru SRST_P_UFS_GRF>, <&cru SRST_MPHY_INIT>;
+            reset-names = "biu", "sys", "ufs", "grf", "mphy";
             reset-gpios = <&gpio4 RK_PD0 GPIO_ACTIVE_LOW>;
         };
     };
diff --git a/Documentation/devicetree/bindings/usb/atmel,at91rm9200-udc.yaml b/Documentation/devicetree/bindings/usb/atmel,at91rm9200-udc.yaml
new file mode 100644
index 0000000..a4eabb9
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/atmel,at91rm9200-udc.yaml
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/atmel,at91rm9200-udc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel AT91 USB Device Controller (UDC)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre@microchip.com>
+  - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+description:
+  The Atmel AT91 USB Device Controller provides USB gadget (device-mode)
+  functionality on AT91 SoCs. It requires a peripheral clock and an AHB
+  clock for operation and may optionally control VBUS power through a GPIO.
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-udc
+      - atmel,at91sam9260-udc
+      - atmel,at91sam9261-udc
+      - atmel,at91sam9263-udc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: pclk
+      - const: hclk
+
+  atmel,vbus-gpio:
+    description: GPIO used to enable or control VBUS power for the USB bus.
+    maxItems: 1
+
+  atmel,matrix:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description: Phandle to the Atmel bus matrix controller.
+
+  atmel,pullup-gpio:
+    description:
+      GPIO controlling the USB D+ pull-up resistor used to signal device
+      connection to the host.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/gpio/gpio.h>
+    gadget@fffa4000 {
+        compatible = "atmel,at91rm9200-udc";
+        reg = <0xfffa4000 0x4000>;
+        interrupts = <11 IRQ_TYPE_LEVEL_HIGH 2>;
+        clocks = <&udc_clk>, <&udpck>;
+        clock-names = "pclk", "hclk";
+        atmel,vbus-gpio = <&pioC 5 GPIO_ACTIVE_HIGH>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/usb/atmel,at91sam9rl-udc.yaml b/Documentation/devicetree/bindings/usb/atmel,at91sam9rl-udc.yaml
new file mode 100644
index 0000000..cdbbd17
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/atmel,at91sam9rl-udc.yaml
@@ -0,0 +1,74 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/atmel,at91sam9rl-udc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel High-Speed USB Device Controller (USBA)
+
+maintainers:
+  - Nicolas Ferre <nicolas.ferre@microchip.com>
+  - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+description:
+  The Atmel High-Speed USB Device Controller (USBA) provides USB 2.0
+  high-speed gadget functionality on several Atmel and Microchip SoCs.
+  The controller requires a peripheral clock and a host clock for operation
+  and may optionally use a GPIO to detect VBUS presence.
+
+properties:
+  compatible:
+    oneOf:
+      - enum:
+          - atmel,at91sam9rl-udc
+          - atmel,at91sam9g45-udc
+          - atmel,sama5d3-udc
+      - items:
+          - const: microchip,lan9662-udc
+          - const: atmel,sama5d3-udc
+      - const: microchip,sam9x60-udc
+
+  reg:
+    maxItems: 2
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    minItems: 2
+    maxItems: 2
+    items:
+      enum: [pclk, hclk]
+
+  atmel,vbus-gpio:
+    description: GPIO used to detect the presence of VBUS, indicating that
+      the USB cable is connected.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/at91.h>
+    #include <dt-bindings/gpio/gpio.h>
+    gadget@fff78000 {
+        compatible = "atmel,at91sam9g45-udc";
+        reg = <0x00600000 0x80000
+               0xfff78000 0x400>;
+        interrupts = <27 IRQ_TYPE_LEVEL_HIGH 0>;
+        clocks = <&pmc PMC_TYPE_PERIPHERAL 27>, <&pmc PMC_TYPE_CORE PMC_UTMI>;
+        clock-names = "pclk", "hclk";
+        atmel,vbus-gpio = <&pioC 15 GPIO_ACTIVE_HIGH>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/usb/atmel-usb.txt b/Documentation/devicetree/bindings/usb/atmel-usb.txt
deleted file mode 100644
index 12183ef..0000000
--- a/Documentation/devicetree/bindings/usb/atmel-usb.txt
+++ /dev/null
@@ -1,125 +0,0 @@
-Atmel SOC USB controllers
-
-OHCI
-
-Required properties:
- - compatible: Should be "atmel,at91rm9200-ohci" for USB controllers
-   used in host mode.
- - reg: Address and length of the register set for the device
- - interrupts: Should contain ohci interrupt
- - clocks: Should reference the peripheral, host and system clocks
- - clock-names: Should contain three strings
-		"ohci_clk" for the peripheral clock
-		"hclk" for the host clock
-		"uhpck" for the system clock
- - num-ports: Number of ports.
- - atmel,vbus-gpio: If present, specifies a gpio that needs to be
-   activated for the bus to be powered.
- - atmel,oc-gpio: If present, specifies a gpio that needs to be
-   activated for the overcurrent detection.
-
-usb0: ohci@500000 {
-	compatible = "atmel,at91rm9200-ohci", "usb-ohci";
-	reg = <0x00500000 0x100000>;
-	clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;
-	clock-names = "ohci_clk", "hclk", "uhpck";
-	interrupts = <20 4>;
-	num-ports = <2>;
-};
-
-EHCI
-
-Required properties:
- - compatible: Should be "atmel,at91sam9g45-ehci" for USB controllers
-   used in host mode.
- - reg: Address and length of the register set for the device
- - interrupts: Should contain ehci interrupt
- - clocks: Should reference the peripheral and the UTMI clocks
- - clock-names: Should contain two strings
-		"ehci_clk" for the peripheral clock
-		"usb_clk" for the UTMI clock
-
-Optional properties:
- - phy_type : For multi port host USB controllers, should be one of
-   "utmi", or "hsic".
-
-usb1: ehci@800000 {
-	compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
-	reg = <0x00800000 0x100000>;
-	interrupts = <22 4>;
-	clocks = <&utmi>, <&uhphs_clk>;
-	clock-names = "usb_clk", "ehci_clk";
-};
-
-AT91 USB device controller
-
-Required properties:
- - compatible: Should be one of the following
-	       "atmel,at91rm9200-udc"
-	       "atmel,at91sam9260-udc"
-	       "atmel,at91sam9261-udc"
-	       "atmel,at91sam9263-udc"
- - reg: Address and length of the register set for the device
- - interrupts: Should contain macb interrupt
- - clocks: Should reference the peripheral and the AHB clocks
- - clock-names: Should contain two strings
-		"pclk" for the peripheral clock
-		"hclk" for the AHB clock
-
-Optional properties:
- - atmel,vbus-gpio: If present, specifies a gpio that needs to be
-   activated for the bus to be powered.
-
-usb1: gadget@fffa4000 {
-	compatible = "atmel,at91rm9200-udc";
-	reg = <0xfffa4000 0x4000>;
-	interrupts = <10 4>;
-	clocks = <&udc_clk>, <&udpck>;
-	clock-names = "pclk", "hclk";
-	atmel,vbus-gpio = <&pioC 5 0>;
-};
-
-Atmel High-Speed USB device controller
-
-Required properties:
- - compatible: Should be one of the following
-	       "atmel,at91sam9rl-udc"
-	       "atmel,at91sam9g45-udc"
-	       "atmel,sama5d3-udc"
-	       "microchip,sam9x60-udc"
-	       "microchip,lan9662-udc"
-	       For "microchip,lan9662-udc" the fallback "atmel,sama5d3-udc"
-	       is required.
- - reg: Address and length of the register set for the device
- - interrupts: Should contain usba interrupt
- - clocks: Should reference the peripheral and host clocks
- - clock-names: Should contain two strings
-		"pclk" for the peripheral clock
-		"hclk" for the host clock
-
-Deprecated property:
- - ep childnode: To specify the number of endpoints and their properties.
-
-Optional properties:
- - atmel,vbus-gpio: If present, specifies a gpio that allows to detect whether
-   vbus is present (USB is connected).
-
-Deprecated child node properties:
- - name: Name of the endpoint.
- - reg: Num of the endpoint.
- - atmel,fifo-size: Size of the fifo.
- - atmel,nb-banks: Number of banks.
- - atmel,can-dma: Boolean to specify if the endpoint support DMA.
- - atmel,can-isoc: Boolean to specify if the endpoint support ISOC.
-
-usb2: gadget@fff78000 {
-	#address-cells = <1>;
-	#size-cells = <0>;
-	compatible = "atmel,at91sam9rl-udc";
-	reg = <0x00600000 0x80000
-	       0xfff78000 0x400>;
-	interrupts = <27 4 0>;
-	clocks = <&utmi>, <&udphs_clk>;
-	clock-names = "hclk", "pclk";
-	atmel,vbus-gpio = <&pioB 19 0>;
-};
diff --git a/Documentation/devicetree/bindings/usb/cdns,usb3.yaml b/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
index f454ddd..a199e5b 100644
--- a/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
+++ b/Documentation/devicetree/bindings/usb/cdns,usb3.yaml
@@ -85,6 +85,7 @@
 
 allOf:
   - $ref: usb-drd.yaml#
+  - $ref: usb-xhci.yaml#
 
 unevaluatedProperties: false
 
diff --git a/Documentation/devicetree/bindings/usb/corechips,sl6341.yaml b/Documentation/devicetree/bindings/usb/corechips,sl6341.yaml
new file mode 100644
index 0000000..8299679
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/corechips,sl6341.yaml
@@ -0,0 +1,79 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/corechips,sl6341.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Corechips SL6341 USB 2.0/3.0 Hub Controller
+
+maintainers:
+  - Alexey Charkov <alchark@flipper.net>
+
+allOf:
+  - $ref: usb-hub.yaml#
+
+properties:
+  compatible:
+    enum:
+      - usb3431,6241
+      - usb3431,6341
+
+  reg: true
+
+  peer-hub: true
+
+  reset-gpios:
+    description: GPIO controlling the RSTN pin.
+
+  vdd1v1-supply:
+    description:
+      The regulator that provides 1.1V core power to the hub.
+
+  vdd3v3-supply:
+    description:
+      The regulator that provides 3.3V IO power to the hub.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    patternProperties:
+      '^port@':
+        $ref: /schemas/graph.yaml#/properties/port
+
+        properties:
+          reg:
+            minimum: 1
+            maximum: 4
+
+required:
+  - compatible
+  - reg
+  - vdd1v1-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    usb {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        /* 2.0 hub */
+        hub_2_0: hub@1 {
+          compatible = "usb3431,6241";
+          reg = <1>;
+          peer-hub = <&hub_3_0>;
+          reset-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+          vdd1v1-supply = <&vdd1v1_hub>;
+        };
+
+        /* 3.0 hub */
+        hub_3_0: hub@2 {
+          compatible = "usb3431,6341";
+          reg = <2>;
+          peer-hub = <&hub_2_0>;
+          reset-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
+          vdd1v1-supply = <&vdd1v1_hub>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
index 73e7a60..66d368e 100644
--- a/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/fsl,imx8mp-dwc3.yaml
@@ -10,6 +10,8 @@
 maintainers:
   - Li Jun <jun.li@nxp.com>
 
+deprecated: true
+
 properties:
   compatible:
     oneOf:
diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
index 601f097..55a5aa7 100644
--- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml
@@ -9,19 +9,6 @@
 maintainers:
   - Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 
-allOf:
-  - $ref: usb-hcd.yaml
-  - if:
-      properties:
-        compatible:
-          not:
-            contains:
-              const: ibm,usb-ehci-440epx
-    then:
-      properties:
-        reg:
-          maxItems: 1
-
 properties:
   compatible:
     oneOf:
@@ -167,6 +154,39 @@
   - reg
   - interrupts
 
+allOf:
+  - $ref: usb-hcd.yaml
+  - if:
+      properties:
+        compatible:
+          not:
+            contains:
+              const: ibm,usb-ehci-440epx
+    then:
+      properties:
+        reg:
+          maxItems: 1
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: atmel,at91sam9g45-ehci
+    then:
+      properties:
+        clock-names:
+          items:
+            - const: usb_clk
+            - const: ehci_clk
+
+        phy_type:
+          enum:
+            - utmi
+            - hsic
+
+      required:
+        - clocks
+        - clock-names
+
 unevaluatedProperties: false
 
 examples:
diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
index 961cbf8..d42f448 100644
--- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml
+++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml
@@ -55,6 +55,7 @@
           - ti,ohci-omap3
       - items:
           - enum:
+              - atmel,at91rm9200-ohci
               - cavium,octeon-6335-ohci
               - nintendo,hollywood-usb-ohci
               - nxp,ohci-nxp
@@ -137,6 +138,24 @@
       The associated ISP1301 device. Necessary for the UDC controller for
       connecting to the USB physical layer.
 
+  atmel,vbus-gpio:
+    description:
+      GPIO used to control or sense the USB VBUS power. Each entry
+      represents a VBUS-related GPIO; count and order may vary by hardware.
+      Entries follow standard GPIO specifier format. A value of 0 indicates
+      an unused or unavailable VBUS signal.
+    minItems: 1
+    maxItems: 3
+
+  atmel,oc-gpio:
+    description:
+      GPIO used to signal USB overcurrent condition. Each entry represents
+      an OC detection GPIO; count and order may vary by hardware. Entries
+      follow standard GPIO specifier format. A value of 0 indicates an
+      unused or unavailable OC signal.
+    minItems: 1
+    maxItems: 3
+
 required:
   - compatible
   - reg
@@ -145,6 +164,28 @@
 allOf:
   - $ref: usb-hcd.yaml
   - if:
+      properties:
+        compatible:
+          contains:
+            const: atmel,at91rm9200-ohci
+    then:
+      properties:
+        clock-names:
+          items:
+            - const: ohci_clk
+            - const: hclk
+            - const: uhpck
+
+      required:
+        - clocks
+        - clock-names
+
+    else:
+      properties:
+        atmel,vbus-gpio: false
+        atmel,oc-gpio: false
+
+  - if:
       not:
         properties:
           compatible:
diff --git a/Documentation/devicetree/bindings/usb/maxim,max33359.yaml b/Documentation/devicetree/bindings/usb/maxim,max33359.yaml
index 3de4dc4..003c0b7 100644
--- a/Documentation/devicetree/bindings/usb/maxim,max33359.yaml
+++ b/Documentation/devicetree/bindings/usb/maxim,max33359.yaml
@@ -32,6 +32,9 @@
     description:
       Properties for usb c connector.
 
+  vbus-supply:
+    description: Regulator to control sourcing Vbus.
+
 required:
   - compatible
   - reg
@@ -53,6 +56,7 @@
             reg = <0x25>;
             interrupt-parent = <&gpa8>;
             interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+            vbus-supply = <&chgin_otg_reg>;
 
             connector {
                 compatible = "usb-c-connector";
@@ -75,6 +79,10 @@
                                        PDO_FIXED(9000, 2000, 0)>;
                 sink-bc12-completion-time-ms = <500>;
                 pd-revision = /bits/ 8 <0x03 0x01 0x01 0x08>;
+                sink-load-step = <150>;
+                sink-load-characteristics = /bits/ 16 <SINK_LOAD_CHAR(0, 1, 1, 2)>;
+                sink-compliance = /bits/ 8 <(COMPLIANCE_LPS | COMPLIANCE_PS1)>;
+                charging-adapter-pdp-milliwatt = <18000>;
             };
         };
     };
diff --git a/Documentation/devicetree/bindings/usb/maxim,max3421.txt b/Documentation/devicetree/bindings/usb/maxim,max3421.txt
deleted file mode 100644
index 90495b1..0000000
--- a/Documentation/devicetree/bindings/usb/maxim,max3421.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Maxim Integrated SPI-based USB 2.0 host controller MAX3421E
-
-Required properties:
- - compatible: Should be "maxim,max3421"
- - spi-max-frequency: maximum frequency for this device must not exceed 26 MHz.
- - reg: chip select number to which this device is connected.
- - maxim,vbus-en-pin: <GPOUTx ACTIVE_LEVEL>
-   GPOUTx is the number (1-8) of the GPOUT pin of MAX3421E to drive Vbus.
-   ACTIVE_LEVEL is 0 or 1.
- - interrupts: the interrupt line description for the interrupt controller.
-   The driver configures MAX3421E for active low level triggered interrupts,
-   configure your interrupt line accordingly.
-
-Example:
-
-	usb@0 {
-		compatible = "maxim,max3421";
-		reg = <0>;
-		maxim,vbus-en-pin = <3 1>;
-		spi-max-frequency = <26000000>;
-		interrupt-parent = <&PIC>;
-		interrupts = <42>;
-	};
diff --git a/Documentation/devicetree/bindings/usb/maxim,max3421.yaml b/Documentation/devicetree/bindings/usb/maxim,max3421.yaml
new file mode 100644
index 0000000..4639be7
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/maxim,max3421.yaml
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/maxim,max3421.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MAXIM MAX3421e USB Peripheral/Host Controller
+
+maintainers:
+  - David Mosberger <davidm@egauge.net>
+
+description: |
+  The controller provides USB2.0 compliant with Full Speed or Low Speed when in
+  the host mode. At peripheral, it operates at Full Speed. At both cases, it
+  uses a SPI interface.
+  Datasheet at:
+    https://www.analog.com/media/en/technical-documentation/data-sheets/max3421e.pdf
+
+properties:
+  compatible:
+    const: maxim,max3421
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  spi-max-frequency:
+    maximum: 26000000
+
+  maxim,vbus-en-pin:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    description:
+      One of eight GPOUT pins to control external VBUS power and the polarity
+      of the active level. It's an array of GPIO number and the active level of it.
+    minItems: 2
+    maxItems: 2
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - maxim,vbus-en-pin
+
+allOf:
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        usb@0 {
+          compatible = "maxim,max3421";
+          reg = <0>;
+          maxim,vbus-en-pin = <3 1>;
+          spi-max-frequency = <26000000>;
+          interrupt-parent = <&gpio>;
+          interrupts = <42>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml b/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
index a812317..c4e1c2d 100644
--- a/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
+++ b/Documentation/devicetree/bindings/usb/microchip,mpfs-musb.yaml
@@ -37,6 +37,9 @@
   clocks:
     maxItems: 1
 
+  resets:
+    maxItems: 1
+
   microchip,ext-vbus-drv:
     description:
       Some ULPI USB PHYs do not support an internal VBUS supply and driving
diff --git a/Documentation/devicetree/bindings/usb/nxp,imx-dwc3.yaml b/Documentation/devicetree/bindings/usb/nxp,imx-dwc3.yaml
new file mode 100644
index 0000000..1911e71
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/nxp,imx-dwc3.yaml
@@ -0,0 +1,123 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright 2026 NXP
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/nxp,imx-dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX Soc USB Controller
+
+maintainers:
+  - Xu Yang <xu.yang_2@nxp.com>
+
+properties:
+  compatible:
+    oneOf:
+      - items:
+          - enum:
+              - nxp,imx94-dwc3
+              - nxp,imx95-dwc3
+          - const: nxp,imx8mp-dwc3
+      - const: nxp,imx8mp-dwc3
+
+  reg:
+    items:
+      - description: DWC3 core registers
+      - description: HSIO Block Control registers
+      - description: Wrapper registers of dwc3 core
+
+  reg-names:
+    items:
+      - const: core
+      - const: blkctl
+      - const: glue
+
+  interrupts:
+    items:
+      - description: DWC3 controller interrupt
+      - description: Wakeup interrupt from glue logic
+
+  interrupt-names:
+    items:
+      - const: dwc_usb3
+      - const: wakeup
+
+  iommus:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: System hsio root clock
+      - description: SoC Bus Clock for AHB/AXI/Native
+      - description: Reference clock for generating ITP when UTMI/ULPI PHY is suspended
+      - description: Suspend clock used for usb wakeup logic
+
+  clock-names:
+    items:
+      - const: hsio
+      - const: bus_early
+      - const: ref
+      - const: suspend
+
+  fsl,permanently-attached:
+    type: boolean
+    description:
+      Indicates if the device attached to a downstream port is
+      permanently attached
+
+  fsl,disable-port-power-control:
+    type: boolean
+    description:
+      Indicates whether the host controller implementation includes port
+      power control. Defines Bit 3 in capability register (HCCPARAMS)
+
+  fsl,over-current-active-low:
+    type: boolean
+    description:
+      Over current signal polarity is active low
+
+  fsl,power-active-low:
+    type: boolean
+    description:
+      Power pad (PWR) polarity is active low
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+  - power-domains
+
+allOf:
+  - $ref: snps,dwc3-common.yaml#
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    usb@4c100000 {
+      compatible = "nxp,imx94-dwc3", "nxp,imx8mp-dwc3";
+      reg = <0x4c100000 0x10000>,
+            <0x4c010010 0x04>,
+            <0x4c1f0000 0x20>;
+      reg-names = "core", "blkctl", "glue";
+      clocks = <&scmi_clk 74>,    //IMX94_CLK_HSIO
+               <&scmi_clk 74>,    //IMX94_CLK_HSIO
+               <&scmi_clk 2>,     //IMX94_CLK_24M
+               <&scmi_clk 1>;     //IMX94_CLK_32K
+      clock-names = "hsio", "bus_early", "ref", "suspend";
+      interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>,
+                   <GIC_SPI 386 IRQ_TYPE_LEVEL_HIGH>;
+      interrupt-names = "dwc_usb3", "wakeup";
+      power-domains = <&scmi_devpd 13>;   //IMX94_PD_HSIO_TOP
+      phys = <&usb3_phy>, <&usb3_phy>;
+      phy-names = "usb2-phy", "usb3-phy";
+      snps,gfladj-refclk-lpm-sel-quirk;
+      snps,parkmode-disable-ss-quirk;
+    };
diff --git a/Documentation/devicetree/bindings/usb/nxp,ptn5110.yaml b/Documentation/devicetree/bindings/usb/nxp,ptn5110.yaml
index 65a8632..581e591 100644
--- a/Documentation/devicetree/bindings/usb/nxp,ptn5110.yaml
+++ b/Documentation/devicetree/bindings/usb/nxp,ptn5110.yaml
@@ -26,6 +26,10 @@
     $ref: /schemas/connector/usb-connector.yaml#
     unevaluatedProperties: false
 
+  orientation-gpios:
+    maxItems: 1
+    description: Optional orientation select control
+
 required:
   - compatible
   - reg
diff --git a/Documentation/devicetree/bindings/usb/ohci-st.txt b/Documentation/devicetree/bindings/usb/ohci-st.txt
deleted file mode 100644
index 1c73557..0000000
--- a/Documentation/devicetree/bindings/usb/ohci-st.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-ST USB OHCI controller
-
-Required properties:
-
- - compatible		: must be "st,st-ohci-300x"
- - reg			: physical base addresses of the controller and length of memory mapped
-			  region
- - interrupts		: one OHCI controller interrupt should be described here
- - clocks		: phandle list of usb clocks
- - clock-names		: should be "ic" for interconnect clock and "clk48"
-See: Documentation/devicetree/bindings/clock/clock-bindings.txt
-
- - phys			: phandle for the PHY device
- - phy-names		: should be "usb"
-
- - resets		: phandle to the powerdown and reset controller for the USB IP
- - reset-names		: should be "power" and "softreset".
-See: Documentation/devicetree/bindings/reset/st,stih407-powerdown.yaml
-See: Documentation/devicetree/bindings/reset/reset.txt
-
-Example:
-
-	ohci0: usb@fe1ffc00 {
-		compatible = "st,st-ohci-300x";
-		reg = <0xfe1ffc00 0x100>;
-		interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
-		clocks = <&clk_s_a1_ls 0>,
-			 <&clockgen_b0 0>;
-		clock-names = "ic", "clk48";
-		phys = <&usb2_phy>;
-		phy-names = "usb";
-
-		resets = <&powerdown STIH416_USB0_POWERDOWN>,
-			 <&softreset STIH416_USB0_SOFTRESET>;
-		reset-names = "power", "softreset";
-	};
diff --git a/Documentation/devicetree/bindings/usb/omap-usb.txt b/Documentation/devicetree/bindings/usb/omap-usb.txt
deleted file mode 100644
index f0dbc5a..0000000
--- a/Documentation/devicetree/bindings/usb/omap-usb.txt
+++ /dev/null
@@ -1,80 +0,0 @@
-OMAP GLUE AND OTHER OMAP SPECIFIC COMPONENTS
-
-OMAP MUSB GLUE
- - compatible : Should be "ti,omap4-musb" or "ti,omap3-musb"
- - ti,hwmods : must be "usb_otg_hs"
- - multipoint : Should be "1" indicating the musb controller supports
-   multipoint. This is a MUSB configuration-specific setting.
- - num-eps : Specifies the number of endpoints. This is also a
-   MUSB configuration-specific setting. Should be set to "16"
- - ram-bits : Specifies the ram address size. Should be set to "12"
- - interface-type : This is a board specific setting to describe the type of
-   interface between the controller and the phy. It should be "0" or "1"
-   specifying ULPI and UTMI respectively.
- - mode : Should be "3" to represent OTG. "1" signifies HOST and "2"
-   represents PERIPHERAL.
- - power : Should be "50". This signifies the controller can supply up to
-   100mA when operating in host mode.
- - usb-phy : the phandle for the PHY device
- - phys : the phandle for the PHY device (used by generic PHY framework)
- - phy-names : the names of the PHY corresponding to the PHYs present in the
-   *phy* phandle.
-
-Optional properties:
- - ctrl-module : phandle of the control module this glue uses to write to
-   mailbox
-
-SOC specific device node entry
-usb_otg_hs: usb_otg_hs@4a0ab000 {
-	compatible = "ti,omap4-musb";
-	ti,hwmods = "usb_otg_hs";
-	multipoint = <1>;
-	num-eps = <16>;
-	ram-bits = <12>;
-	ctrl-module = <&omap_control_usb>;
-	phys = <&usb2_phy>;
-	phy-names = "usb2-phy";
-};
-
-Board specific device node entry
-&usb_otg_hs {
-	interface-type = <1>;
-	mode = <3>;
-	power = <50>;
-};
-
-OMAP DWC3 GLUE
- - compatible : Should be
-	* "ti,dwc3" for OMAP5 and DRA7
-	* "ti,am437x-dwc3" for AM437x
- - ti,hwmods : Should be "usb_otg_ss"
- - reg : Address and length of the register set for the device.
- - interrupts : The irq number of this device that is used to interrupt the
-   MPU
- - #address-cells, #size-cells : Must be present if the device has sub-nodes
- - utmi-mode : controls the source of UTMI/PIPE status for VBUS and OTG ID.
-   It should be set to "1" for HW mode and "2" for SW mode.
- - ranges: the child address space are mapped 1:1 onto the parent address space
-
-Optional Properties:
- - extcon : phandle for the extcon device omap dwc3 uses to detect
-   connect/disconnect events.
- - vbus-supply : phandle to the regulator device tree node if needed.
-
-Sub-nodes:
-The dwc3 core should be added as subnode to omap dwc3 glue.
-- dwc3 :
-   The binding details of dwc3 can be found in:
-   Documentation/devicetree/bindings/usb/snps,dwc3.yaml
-
-omap_dwc3 {
-	compatible = "ti,dwc3";
-	ti,hwmods = "usb_otg_ss";
-	reg = <0x4a020000 0x1ff>;
-	interrupts = <0 93 4>;
-	#address-cells = <1>;
-	#size-cells = <1>;
-	utmi-mode = <2>;
-	ranges;
-};
-
diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
index 7d784a6..8201656 100644
--- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -24,6 +24,7 @@
   compatible:
     items:
       - enum:
+          - qcom,eliza-dwc3
           - qcom,glymur-dwc3
           - qcom,glymur-dwc3-mp
           - qcom,ipq4019-dwc3
@@ -153,8 +154,6 @@
 
   wakeup-source: true
 
-# Required child node:
-
 required:
   - compatible
   - reg
@@ -175,6 +174,7 @@
     then:
       properties:
         clocks:
+          minItems: 3
           maxItems: 3
         clock-names:
           items:
@@ -203,6 +203,7 @@
         compatible:
           contains:
             enum:
+              - qcom,ipq5424-dwc3
               - qcom,ipq9574-dwc3
               - qcom,kaanapali-dwc3
               - qcom,msm8953-dwc3
@@ -222,6 +223,7 @@
     then:
       properties:
         clocks:
+          minItems: 5
           maxItems: 5
         clock-names:
           items:
@@ -264,6 +266,7 @@
     then:
       properties:
         clocks:
+          minItems: 4
           maxItems: 4
         clock-names:
           items:
@@ -283,6 +286,7 @@
     then:
       properties:
         clocks:
+          minItems: 4
           maxItems: 4
         clock-names:
           items:
@@ -303,6 +307,7 @@
     then:
       properties:
         clocks:
+          minItems: 9
           maxItems: 9
         clock-names:
           items:
@@ -346,14 +351,17 @@
         compatible:
           contains:
             enum:
+              - qcom,eliza-dwc3
               - qcom,milos-dwc3
               - qcom,qcm2290-dwc3
               - qcom,qcs615-dwc3
               - qcom,sar2130p-dwc3
               - qcom,sc8180x-dwc3
               - qcom,sc8180x-dwc3-mp
+              - qcom,sm4250-dwc3
               - qcom,sm6115-dwc3
               - qcom,sm6125-dwc3
+              - qcom,sm6375-dwc3
               - qcom,sm8150-dwc3
               - qcom,sm8250-dwc3
               - qcom,sm8450-dwc3
@@ -363,6 +371,7 @@
       properties:
         clocks:
           minItems: 6
+          maxItems: 6
         clock-names:
           items:
             - const: cfg_noc
@@ -404,6 +413,7 @@
     then:
       properties:
         clocks:
+          minItems: 7
           maxItems: 7
         clock-names:
           items:
@@ -446,6 +456,7 @@
               - qcom,msm8996-dwc3
               - qcom,qcs404-dwc3
               - qcom,sdm660-dwc3
+              - qcom,sm4250-dwc3
               - qcom,sm6115-dwc3
               - qcom,sm6125-dwc3
     then:
@@ -472,6 +483,7 @@
     then:
       properties:
         interrupts:
+          minItems: 4
           maxItems: 4
         interrupt-names:
           items:
@@ -485,6 +497,26 @@
         compatible:
           contains:
             enum:
+              - qcom,ipq5424-dwc3
+              - qcom,ipq9574-dwc3
+    then:
+      properties:
+        interrupts:
+          minItems: 5
+          maxItems: 5
+        interrupt-names:
+          items:
+            - const: dwc_usb3
+            - const: pwr_event
+            - const: qusb2_phy
+            - const: dp_hs_phy_irq
+            - const: dm_hs_phy_irq
+
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
               - qcom,glymur-dwc3
               - qcom,milos-dwc3
               - qcom,x1e80100-dwc3
@@ -500,13 +532,14 @@
             - const: pwr_event
             - const: dp_hs_phy_irq
             - const: dm_hs_phy_irq
-            - const: ss_phy_irq
+            - enum: [hs_phy_irq, ss_phy_irq]
 
   - if:
       properties:
         compatible:
           contains:
             enum:
+              - qcom,eliza-dwc3
               - qcom,ipq4019-dwc3
               - qcom,ipq8064-dwc3
               - qcom,kaanapali-dwc3
@@ -523,8 +556,8 @@
               - qcom,sdx55-dwc3
               - qcom,sdx65-dwc3
               - qcom,sdx75-dwc3
-              - qcom,sm4250-dwc3
               - qcom,sm6350-dwc3
+              - qcom,sm6375-dwc3
               - qcom,sm8150-dwc3
               - qcom,sm8250-dwc3
               - qcom,sm8350-dwc3
diff --git a/Documentation/devicetree/bindings/usb/renesas,upd720201-pci.yaml b/Documentation/devicetree/bindings/usb/renesas,upd720201-pci.yaml
new file mode 100644
index 0000000..4e890d0
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/renesas,upd720201-pci.yaml
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/renesas,upd720201-pci.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: UPD720201/UPD720202 USB 3.0 xHCI Host Controller (PCIe)
+
+maintainers:
+  - Neil Armstrong <neil.armstrong@linaro.org>
+
+description:
+  UPD720201 USB 3.0 xHCI Host Controller via PCIe x1 Gen2 interface.
+  The UPD720202 supports up to two downstream ports, while UPD720201
+  supports up to four downstream USB 3.0 rev1.0 ports.
+
+properties:
+  compatible:
+    enum:
+      - pci1912,0014 # UPD720201
+      - pci1912,0015 # UPD720202
+
+  reg:
+    maxItems: 1
+
+  avdd33-supply:
+    description: +3.3 V power supply for analog circuit
+
+  vdd10-supply:
+    description: +1.05 V power supply
+
+  vdd33-supply:
+    description: +3.3 V power supply
+
+required:
+  - compatible
+  - reg
+  - avdd33-supply
+  - vdd10-supply
+  - vdd33-supply
+
+allOf:
+  - $ref: usb-xhci.yaml
+
+additionalProperties: true
+
+examples:
+  - |
+    pcie@0 {
+        reg = <0x0 0x1000>;
+        ranges = <0x02000000 0x0 0x100000 0x10000000 0x0 0x0>;
+        #address-cells = <3>;
+        #size-cells = <2>;
+        device_type = "pci";
+
+        usb-controller@0 {
+            compatible = "pci1912,0014";
+            reg = <0x0 0x0 0x0 0x0 0x0>;
+            avdd33-supply = <&avdd33_reg>;
+            vdd10-supply = <&vdd10_reg>;
+            vdd33-supply = <&vdd33_reg>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/usb/richtek,rt1711h.yaml b/Documentation/devicetree/bindings/usb/richtek,rt1711h.yaml
index ae611f7..7ded363 100644
--- a/Documentation/devicetree/bindings/usb/richtek,rt1711h.yaml
+++ b/Documentation/devicetree/bindings/usb/richtek,rt1711h.yaml
@@ -18,11 +18,21 @@
 
 properties:
   compatible:
-    enum:
-      - richtek,rt1711h
-      - richtek,rt1715
+    oneOf:
+      - enum:
+          - richtek,rt1711h
+          - richtek,rt1715
+      - items:
+          - enum:
+              - hynetek,husb311
+          - const: richtek,rt1711h
+      - items:
+          - enum:
+              - etekmicro,et7304
+          - const: richtek,rt1715
     description:
-      RT1711H support PD20, RT1715 support PD30 except Fast Role Swap.
+      RT1711H support PD20, ET7304 and RT1715 support PD30 except Fast Role Swap.
+      HUSB311 is a rebrand of RT1711H which is pin and register compatible.
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/usb/spacemit,k1-dwc3.yaml b/Documentation/devicetree/bindings/usb/spacemit,k1-dwc3.yaml
index 0f0b5e0..cc27b36 100644
--- a/Documentation/devicetree/bindings/usb/spacemit,k1-dwc3.yaml
+++ b/Documentation/devicetree/bindings/usb/spacemit,k1-dwc3.yaml
@@ -27,7 +27,9 @@
 
 properties:
   compatible:
-    const: spacemit,k1-dwc3
+    enum:
+      - spacemit,k1-dwc3
+      - spacemit,k3-dwc3
 
   reg:
     maxItems: 1
@@ -42,11 +44,13 @@
     maxItems: 1
 
   phys:
+    minItems: 1
     items:
       - description: phandle to USB2/HS PHY
       - description: phandle to USB3/SS PHY
 
   phy-names:
+    minItems: 1
     items:
       - const: usb2-phy
       - const: usb3-phy
diff --git a/Documentation/devicetree/bindings/usb/st,st-ohci-300x.yaml b/Documentation/devicetree/bindings/usb/st,st-ohci-300x.yaml
new file mode 100644
index 0000000..a225bf5
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/st,st-ohci-300x.yaml
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/st,st-ohci-300x.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics USB OHCI Controller
+
+maintainers:
+  - Peter Griffin <peter.griffin@linaro.org>
+
+description:
+  The STMicroelectronics USB Open Host Controller Interface (OHCI)
+  compliant USB host controller found in ST platforms. The controller
+  provides full- and low-speed USB host functionality and interfaces
+  with an external USB PHY. It requires dedicated clock, reset, and
+  interrupt resources for proper operation.
+
+allOf:
+  - $ref: /schemas/usb/usb-hcd.yaml#
+
+properties:
+  compatible:
+    const: st,st-ohci-300x
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 2
+
+  clock-names:
+    items:
+      - const: ic
+      - const: clk48
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    items:
+      - const: usb
+
+  resets:
+    maxItems: 2
+
+  reset-names:
+    items:
+      - const: power
+      - const: softreset
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
+  - phys
+  - phy-names
+  - resets
+  - reset-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/stih407-resets.h>
+    usb@fe1ffc00 {
+        compatible = "st,st-ohci-300x";
+        reg = <0xfe1ffc00 0x100>;
+        interrupts = <GIC_SPI 149 IRQ_TYPE_NONE>;
+        clocks = <&clk_s_a1_ls 0>,
+                 <&clockgen_b0 0>;
+        clock-names = "ic", "clk48";
+        phys = <&usb2_phy>;
+        phy-names = "usb";
+        resets = <&powerdown STIH407_USB2_PORT0_POWERDOWN>,
+                 <&softreset STIH407_USB2_PORT0_SOFTRESET>;
+        reset-names = "power", "softreset";
+    };
+...
diff --git a/Documentation/devicetree/bindings/usb/starfive,jhb100-dwc3.yaml b/Documentation/devicetree/bindings/usb/starfive,jhb100-dwc3.yaml
new file mode 100644
index 0000000..fbabe99
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/starfive,jhb100-dwc3.yaml
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/starfive,jhb100-dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: StarFive JHB100 DWC3 USB SoC Controller
+
+maintainers:
+  - Minda Chen <minda.chen@starfivetech.com>
+
+description:
+  The USB DRD controller on JHB100 BMC SoC.
+
+allOf:
+  - $ref: snps,dwc3-common.yaml#
+
+properties:
+  compatible:
+    const: starfive,jhb100-dwc3
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: USB main enable clk
+      - description: DWC3 bus early clock
+      - description: DWC3 ref clock
+
+  clock-names:
+    items:
+      - const: main
+      - const: bus_early
+      - const: ref
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - interrupts
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    usb@11800000 {
+        compatible = "starfive,jhb100-dwc3";
+        reg = <0x11800000 0x10000>;
+        clocks = <&usbcrg 9>,
+                 <&usbcrg 5>,
+                 <&usbcrg 6>;
+        clock-names = "main", "bus_early", "ref";
+        resets = <&usbcrg 4>;
+        interrupts = <105>;
+        dr_mode = "host";
+    };
diff --git a/Documentation/devicetree/bindings/usb/terminus,fe11.yaml b/Documentation/devicetree/bindings/usb/terminus,fe11.yaml
new file mode 100644
index 0000000..645f97d
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/terminus,fe11.yaml
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/terminus,fe11.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Terminus FE1.1/1.1S USB 2.0 Hub Controller
+
+maintainers:
+  - Yixun Lan <dlan@kernel.org>
+
+allOf:
+  - $ref: usb-hub.yaml#
+
+properties:
+  compatible:
+    enum:
+      - usb1a40,0101
+
+  reg: true
+
+  reset-gpios:
+    description:
+      GPIO controlling the RESET#.
+
+  vdd-supply:
+    description:
+      Regulator supply to the hub, one of 3.3V or 5V can be chosen.
+
+  ports:
+    $ref: /schemas/graph.yaml#/properties/ports
+
+    patternProperties:
+      '^port@':
+        $ref: /schemas/graph.yaml#/properties/port
+
+        properties:
+          reg:
+            minimum: 1
+            maximum: 4
+
+required:
+  - compatible
+  - reg
+  - vdd-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    usb {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        hub@1 {
+            compatible = "usb1a40,0101";
+            reg = <1>;
+            reset-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
+            vdd-supply = <&vcc_5v>;
+        };
+    };
diff --git a/Documentation/devicetree/bindings/usb/ti,dwc3.yaml b/Documentation/devicetree/bindings/usb/ti,dwc3.yaml
new file mode 100644
index 0000000..77ac11c
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ti,dwc3.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/ti,dwc3.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments OMAP DWC3 USB Glue Layer
+
+maintainers:
+  - Felipe Balbi <balbi@ti.com>
+
+description:
+  Texas Instruments glue layer for Synopsys DesignWare USB3 (DWC3)
+  controller on OMAP and AM43xx SoCs. Manages SoC-specific integration
+  including register mapping, interrupt routing, UTMI/PIPE interface mode
+  selection (HW/SW), and child DWC3 core instantiation via address space
+  translation. Supports both legacy single-instance and multi-instance
+  (numbered) configurations.
+
+properties:
+  compatible:
+    enum:
+      - ti,dwc3
+      - ti,am437x-dwc3
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  utmi-mode:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Controls the source of UTMI/PIPE status for VBUS and OTG ID.
+      1 for HW mode, 2 for SW mode.
+    enum: [1, 2]
+
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+  ranges: true
+
+  extcon:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle for the extcon device used to detect connect/
+      disconnect events.
+
+  vbus-supply:
+    description: Phandle to the regulator device tree node if needed.
+
+patternProperties:
+  "^usb@[0-9a-f]+$":
+    type: object
+    $ref: snps,dwc3.yaml#
+    unevaluatedProperties: false
+
+required:
+  - reg
+  - compatible
+  - interrupts
+  - "#address-cells"
+  - "#size-cells"
+  - utmi-mode
+  - ranges
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    omap_dwc3_1@0 {
+        compatible = "ti,dwc3";
+        reg = <0x0 0x10000>;
+        interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+        #address-cells = <1>;
+        #size-cells = <1>;
+        utmi-mode = <2>;
+        ranges = <0 0 0x20000>;
+
+        usb@10000 {
+            compatible = "snps,dwc3";
+            reg = <0x10000 0x17000>;
+            interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+                         <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+            interrupt-names = "peripheral", "host", "otg";
+            phys = <&usb2_phy1>, <&usb3_phy1>;
+            phy-names = "usb2-phy", "usb3-phy";
+            maximum-speed = "super-speed";
+            dr_mode = "otg";
+            snps,dis_u3_susphy_quirk;
+            snps,dis_u2_susphy_quirk;
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/usb/ti,omap4-musb.yaml b/Documentation/devicetree/bindings/usb/ti,omap4-musb.yaml
new file mode 100644
index 0000000..a3d15f2
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/ti,omap4-musb.yaml
@@ -0,0 +1,120 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/usb/ti,omap4-musb.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Texas Instruments OMAP MUSB USB OTG Controller
+
+maintainers:
+  - Felipe Balbi <balbi@ti.com>
+
+description:
+  Texas Instruments glue layer for the Mentor Graphics MUSB OTG controller.
+  Handles SoC-specific integration including PHY interface bridging(ULPI/
+  UTMI), interrupt aggregation, DMA engine coordination (internal/
+  external), VBUS/session control via control module mailbox, and
+  clock/reset management. Provides fixed hardware configuration parameters
+  to the generic MUSB core driver.
+
+properties:
+  compatible:
+    enum:
+      - ti,omap3-musb
+      - ti,omap4-musb
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    minItems: 1
+    maxItems: 2
+
+  interrupt-names:
+    minItems: 1
+    items:
+      - const: mc
+      - const: dma
+
+  multipoint:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Indicates the MUSB controller supports multipoint. This is a MUSB
+      configuration-specific setting.
+    const: 1
+
+  num-eps:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Specifies the number of endpoints. This is a MUSB configuration
+      specific setting.
+    const: 16
+
+  ram-bits:
+    description: Specifies the RAM address size.
+    const: 12
+
+  interface-type:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Describes the type of interface between the controller and the PHY.
+      0 for ULPI, 1 for UTMI.
+    enum: [0, 1]
+
+  mode:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description: 1 for HOST, 2 for PERIPHERAL, 3 for OTG.
+    enum: [1, 2, 3]
+
+  power:
+    $ref: /schemas/types.yaml#/definitions/uint32
+    description:
+      Indicates the maximum current the controller can supply when
+      operating in host mode. A value of 50 corresponds to 100 mA, and a
+      value of 150 corresponds to 300 mA.
+    enum: [50, 150]
+
+  phys:
+    maxItems: 1
+
+  phy-names:
+    const: usb2-phy
+
+  usb-phy:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description: Phandle for the PHY device.
+    deprecated: true
+
+  ctrl-module:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle of the control module this glue uses to write to mailbox.
+
+required:
+  - reg
+  - compatible
+  - interrupts
+  - interrupt-names
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    usb@4a0ab000 {
+        compatible = "ti,omap4-musb";
+        reg = <0x4a0ab000 0x1000>;
+        interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "mc", "dma";
+        multipoint = <1>;
+        num-eps = <16>;
+        ram-bits = <12>;
+        ctrl-module = <&omap_control_usb>;
+        phys = <&usb2_phy>;
+        phy-names = "usb2-phy";
+        interface-type = <1>;
+        mode = <3>;
+        power = <50>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/usb/ti,usb8041.yaml b/Documentation/devicetree/bindings/usb/ti,usb8041.yaml
index 5e3eae9..07e13fa 100644
--- a/Documentation/devicetree/bindings/usb/ti,usb8041.yaml
+++ b/Documentation/devicetree/bindings/usb/ti,usb8041.yaml
@@ -11,6 +11,7 @@
 
 allOf:
   - $ref: usb-device.yaml#
+  - $ref: usb-hub.yaml#
 
 properties:
   compatible:
@@ -30,17 +31,20 @@
     description:
       VDD power supply to the hub
 
-  peer-hub:
-    $ref: /schemas/types.yaml#/definitions/phandle
-    description:
-      phandle to the peer hub on the controller.
+  peer-hub: true
+
+patternProperties:
+  '^.*@[1-9a-f][0-9a-f]*$':
+    description: The hard wired USB devices
+    type: object
+    $ref: /schemas/usb/usb-device.yaml
+    additionalProperties: true
 
 required:
   - compatible
   - reg
-  - peer-hub
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
@@ -56,7 +60,14 @@
             compatible = "usb451,8142";
             reg = <1>;
             peer-hub = <&hub_3_0>;
+            #address-cells = <1>;
+            #size-cells = <0>;
             reset-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>;
+
+            hub@1 {
+              compatible = "usb123,4567";
+              reg = <1>;
+            };
         };
 
         /* 3.0 hub on port 2 */
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 6339988..28784d6 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -365,6 +365,8 @@
     description: CORERIVER Semiconductor Co.,Ltd.
   "^corpro,.*":
     description: Chengdu Corpro Technology Co., Ltd.
+  "^corechips,.*":
+    description: Shenzhen Corechips Microelectronics Co., Ltd.
   "^cortina,.*":
     description: Cortina Systems, Inc.
   "^cosmic,.*":
@@ -547,6 +549,8 @@
     description: ESTeem Wireless Modems
   "^eswin,.*":
     description: Beijing ESWIN Technology Group Co. Ltd.
+  "^etekmicro,.*":
+    description: Wuxi ETEK Micro-Electronics Co.,Ltd.
   "^ettus,.*":
     description: NI Ettus Research
   "^eukrea,.*":
@@ -751,6 +755,8 @@
     description: Hycon Technology Corp.
   "^hydis,.*":
     description: Hydis Technologies
+  "^hynetek,.*":
+    description: Hynetek Semiconductor Co., Ltd.
   "^hynitron,.*":
     description: Shanghai Hynitron Microelectronics Co. Ltd.
   "^hynix,.*":
diff --git a/Documentation/driver-api/clk.rst b/Documentation/driver-api/clk.rst
index 93bab53..c6aca81 100644
--- a/Documentation/driver-api/clk.rst
+++ b/Documentation/driver-api/clk.rst
@@ -77,9 +77,6 @@
 		void		(*disable_unused)(struct clk_hw *hw);
 		unsigned long	(*recalc_rate)(struct clk_hw *hw,
 						unsigned long parent_rate);
-		long		(*round_rate)(struct clk_hw *hw,
-						unsigned long rate,
-						unsigned long *parent_rate);
 		int		(*determine_rate)(struct clk_hw *hw,
 						  struct clk_rate_request *req);
 		int		(*set_parent)(struct clk_hw *hw, u8 index);
@@ -220,9 +217,7 @@
    +----------------+------+-------------+---------------+-------------+------+
    |.recalc_rate    |      | y           |               |             |      |
    +----------------+------+-------------+---------------+-------------+------+
-   |.round_rate     |      | y [1]_      |               |             |      |
-   +----------------+------+-------------+---------------+-------------+------+
-   |.determine_rate |      | y [1]_      |               |             |      |
+   |.determine_rate |      | y           |               |             |      |
    +----------------+------+-------------+---------------+-------------+------+
    |.set_rate       |      | y           |               |             |      |
    +----------------+------+-------------+---------------+-------------+------+
@@ -238,8 +233,6 @@
    |.init           |      |             |               |             |      |
    +----------------+------+-------------+---------------+-------------+------+
 
-.. [1] either one of round_rate or determine_rate is required.
-
 Finally, register your clock at run-time with a hardware-specific
 registration function.  This function simply populates struct clk_foo's
 data and then passes the common struct clk parameters to the framework
diff --git a/Documentation/driver-api/infiniband.rst b/Documentation/driver-api/infiniband.rst
index 10d8be9..d48f246 100644
--- a/Documentation/driver-api/infiniband.rst
+++ b/Documentation/driver-api/infiniband.rst
@@ -92,21 +92,6 @@
 .. kernel-doc:: drivers/infiniband/ulp/iser/iser_verbs.c
    :internal:
 
-Omni-Path (OPA) Virtual NIC support
------------------------------------
-
-.. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_internal.h
-   :internal:
-
-.. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.h
-   :internal:
-
-.. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_vema_iface.c
-   :internal:
-
-.. kernel-doc:: drivers/infiniband/ulp/opa_vnic/opa_vnic_vema.c
-   :internal:
-
 InfiniBand SCSI RDMA protocol target support
 --------------------------------------------
 
diff --git a/Documentation/features/vm/ioremap_prot/arch-support.txt b/Documentation/features/vm/ioremap_prot/arch-support.txt
index 1638c2cb..c0a2d8f 100644
--- a/Documentation/features/vm/ioremap_prot/arch-support.txt
+++ b/Documentation/features/vm/ioremap_prot/arch-support.txt
@@ -20,7 +20,7 @@
     |    openrisc: | TODO |
     |      parisc: | TODO |
     |     powerpc: |  ok  |
-    |       riscv: | TODO |
+    |       riscv: |  ok  |
     |        s390: |  ok  |
     |          sh: |  ok  |
     |       sparc: | TODO |
diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst
index 8025df6..8421ea2 100644
--- a/Documentation/filesystems/locking.rst
+++ b/Documentation/filesystems/locking.rst
@@ -398,6 +398,7 @@
 	bool (*lm_breaker_owns_lease)(struct file_lock *);
         bool (*lm_lock_expirable)(struct file_lock *);
         void (*lm_expire_lock)(void);
+        bool (*lm_breaker_timedout)(struct file_lease *);
 
 locking rules:
 
@@ -412,6 +413,7 @@
 lm_lock_expirable	yes		no			no
 lm_expire_lock		no		no			yes
 lm_open_conflict	yes		no			no
+lm_breaker_timedout     yes             no                      no
 ======================	=============	=================	=========
 
 buffer_head
diff --git a/Documentation/filesystems/nfs/exporting.rst b/Documentation/filesystems/nfs/exporting.rst
index a01d9b9..4aa59b0 100644
--- a/Documentation/filesystems/nfs/exporting.rst
+++ b/Documentation/filesystems/nfs/exporting.rst
@@ -206,3 +206,88 @@
     all of an inode's dirty data on last close. Exports that behave this
     way should set EXPORT_OP_FLUSH_ON_CLOSE so that NFSD knows to skip
     waiting for writeback when closing such files.
+
+Signed Filehandles
+------------------
+
+To protect against filehandle guessing attacks, the Linux NFS server can be
+configured to sign filehandles with a Message Authentication Code (MAC).
+
+Standard NFS filehandles are often predictable. If an attacker can guess
+a valid filehandle for a file they do not have permission to access via
+directory traversal, they may be able to bypass path-based permissions
+(though they still remain subject to inode-level permissions).
+
+Signed filehandles prevent this by appending a MAC to the filehandle
+before it is sent to the client. Upon receiving a filehandle back from a
+client, the server re-calculates the MAC using its internal key and
+verifies it against the one provided. If the signatures do not match,
+the server treats the filehandle as invalid (returning NFS[34]ERR_STALE).
+
+Note that signing filehandles provides integrity and authenticity but
+not confidentiality. The contents of the filehandle remain visible to
+the client; they simply cannot be forged or modified.
+
+Configuration
+~~~~~~~~~~~~~
+
+To enable signed filehandles, the administrator must provide a signing
+key to the kernel and enable the "sign_fh" export option.
+
+1. Providing a Key
+   The signing key is managed via the nfsd netlink interface. This key
+   is per-network-namespace and must be set before any exports using
+   "sign_fh" become active.
+
+2. Export Options
+   The feature is controlled on a per-export basis in /etc/exports:
+
+   sign_fh
+     Enables signing for all filehandles generated under this export.
+
+   no_sign_fh
+     (Default) Disables signing.
+
+Key Management and Rotation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The security of this mechanism relies entirely on the secrecy of the
+signing key.
+
+Initial Setup:
+  The key should be generated using a high-quality random source and
+  loaded early in the boot process or during the nfs-server startup
+  sequence.
+
+Changing Keys:
+  If a key is changed while clients have active mounts, existing
+  filehandles held by those clients will become invalid, resulting in
+  "Stale file handle" errors on the client side.
+
+Safe Rotation:
+  Currently, there is no mechanism for "graceful" key rotation
+  (maintaining multiple valid keys). Changing the key is an atomic
+  operation that immediately invalidates all previous signatures.
+
+Transitioning Exports
+~~~~~~~~~~~~~~~~~~~~~
+
+When adding or removing the "sign_fh" flag from an active export, the
+following behaviors should be expected:
+
++-------------------+---------------------------------------------------+
+| Change            | Result for Existing Clients                       |
++===================+===================================================+
+| Adding sign_fh    | Clients holding unsigned filehandles will find    |
+|                   | them rejected, as the server now expects a        |
+|                   | signature.                                        |
++-------------------+---------------------------------------------------+
+| Removing sign_fh  | Clients holding signed filehandles will find them |
+|                   | rejected, as the server now expects the           |
+|                   | filehandle to end at its traditional boundary     |
+|                   | without a MAC.                                    |
++-------------------+---------------------------------------------------+
+
+Because filehandles are often cached persistently by clients, adding or
+removing this option should generally be done during a scheduled maintenance
+window involving a NFS client unmount/remount.
diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index d02aa57..fdf0744 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -1368,6 +1368,7 @@
 
 lookup_one_qstr_excl() is no longer exported - use start_creating() or
 similar.
+
 ---
 
 ** mandatory**
@@ -1375,3 +1376,12 @@
 lock_rename(), lock_rename_child(), unlock_rename() are no
 longer available.  Use start_renaming() or similar.
 
+---
+
+**recommended**
+
+If you really need to iterate through dentries for given inode, use
+for_each_alias(dentry, inode) instead of hlist_for_each_entry; better
+yet, see if any of the exported primitives could be used instead of
+the entire loop.  You still need to hold ->i_lock of the inode over
+either form of manual loop.
diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
index 7a4e67a..db6167b 100644
--- a/Documentation/filesystems/proc.rst
+++ b/Documentation/filesystems/proc.rst
@@ -565,6 +565,10 @@
 naturally aligned THP pages of any currently enabled size. 1 if true, 0
 otherwise.
 
+If both the kernel and the CPU support protection keys (pkeys),
+"ProtectionKey" indicates the memory protection key associated with the
+virtual memory area.
+
 "VmFlags" field deserves a separate description. This member represents the
 kernel flags associated with the particular virtual memory area in two letter
 encoded manner. The codes are the following:
diff --git a/Documentation/iio/ad4030.rst b/Documentation/iio/ad4030.rst
index b57424b..9caafa4 100644
--- a/Documentation/iio/ad4030.rst
+++ b/Documentation/iio/ad4030.rst
@@ -92,6 +92,45 @@
 In this mode, both channels conversion results are bit interleaved one SDO line.
 As such the wiring is the same as `One lane mode`_.
 
+SPI offload wiring
+^^^^^^^^^^^^^^^^^^
+
+.. code-block::
+
+    +-------------+         +-------------+
+    |         CNV |<-----+--| GPIO        |
+    |             |      +--| PWM0        |
+    |             |         |             |
+    |             |      +--| PWM1        |
+    |             |      |  +-------------+
+    |             |      +->| TRIGGER     |
+    |          CS |<--------| CS          |
+    |             |         |             |
+    |     ADC     |         |     SPI     |
+    |             |         |             |
+    |         SDI |<--------| SDO         |
+    |         SDO |-------->| SDI         |
+    |        SCLK |<--------| SCLK        |
+    +-------------+         +-------------+
+
+In this mode, both the ``cnv-gpios`` and a ``pwms`` properties are required.
+The ``pwms`` property specifies the PWM that is connected to the ADC CNV pin.
+The SPI offload will have a ``trigger-sources`` property to indicate the SPI
+offload (PWM) trigger source. For AD4030 and similar ADCs, there are two
+possible data transfer zones for sample N. One of them (zone 1) starts after the
+data conversion for sample N is complete while the other one (zone 2) starts 9.8
+nanoseconds after the rising edge of CNV for sample N + 1.
+
+The configuration depicted in the above diagram is intended to perform data
+transfer in zone 2. To achieve high sample rates while meeting ADC timing
+requirements, an offset is added between the rising edges of PWM0 and PWM1 to
+delay the SPI transfer until 9.8 nanoseconds after CNV rising edge. This
+requires a specialized PWM controller that can provide such an offset.
+The `AD4630-FMC HDL project`_, for example, can be configured to sample AD4030
+data during zone 2 data read window.
+
+.. _AD4630-FMC HDL project: https://analogdevicesinc.github.io/hdl/projects/ad4630_fmc/index.html
+
 SPI Clock mode
 --------------
 
diff --git a/Documentation/iio/ad7191.rst b/Documentation/iio/ad7191.rst
index 977d4fe..fd6a23a 100644
--- a/Documentation/iio/ad7191.rst
+++ b/Documentation/iio/ad7191.rst
@@ -63,11 +63,11 @@
 
 The AD7191 supports both internal and external clock sources:
 
-- When CLKSEL pin is tied LOW: Uses internal 4.92MHz clock (no clock property
+- When CLKSEL pin is ACTIVE: Uses internal 4.92MHz clock (no clock property
   needed)
-- When CLKSEL pin is tied HIGH: Requires external clock source
+- When CLKSEL pin is INACTIVE: Requires external clock source
   - Can be a crystal between MCLK1 and MCLK2 pins
-  - Or a CMOS-compatible clock driving MCLK2 pin
+  - Or a CMOS-compatible clock driving MCLK1 pin and MCLK2 left unconnected
   - Must specify the "clocks" property in device tree when using external clock
 
 SPI Interface Requirements
diff --git a/Documentation/iio/adxl345.rst b/Documentation/iio/adxl345.rst
index bb19d64..978f746 100644
--- a/Documentation/iio/adxl345.rst
+++ b/Documentation/iio/adxl345.rst
@@ -12,16 +12,21 @@
 * `ADXL345 <https://www.analog.com/ADXL345>`_
 * `ADXL375 <https://www.analog.com/ADXL375>`_
 
-The ADXL345 is a generic purpose low power, 3-axis accelerometer with selectable
-measurement ranges. The ADXL345 supports the ±2 g, ±4 g, ±8 g, and ±16 g ranges.
+The ADXL345 is a general-purpose, low-power, 3-axis accelerometer with selectable
+measurement ranges. The ADXL345 supports the following ranges:
+
+- ±2g  (approx. ±19.61 m/s^2)
+- ±4g  (approx. ±39.23 m/s^2)
+- ±8g  (approx. ±78.45 m/s^2)
+- ±16g (approx. ±156.91 m/s^2)
 
 2. Device Attributes
 ====================
 
-Each IIO device, has a device folder under ``/sys/bus/iio/devices/iio:deviceX``,
+Each IIO device has a device folder under ``/sys/bus/iio/devices/iio:deviceX``,
 where X is the IIO index of the device. Under these folders reside a set of
 device files, depending on the characteristics and features of the hardware
-device in questions. These files are consistently generalized and documented in
+device in question. These files are consistently generalized and documented in
 the IIO ABI documentation.
 
 The following table shows the ADXL345 related device files, found in the
@@ -42,7 +47,7 @@
 +-------------------------------------------+----------------------------------------------------------+
 | in_accel_x_raw                            | Raw X-axis accelerometer channel value.                  |
 +-------------------------------------------+----------------------------------------------------------+
-| in_accel_y_calibbias                      | y-axis acceleration offset correction                    |
+| in_accel_y_calibbias                      | Y-axis acceleration offset correction                    |
 +-------------------------------------------+----------------------------------------------------------+
 | in_accel_y_raw                            | Raw Y-axis accelerometer channel value.                  |
 +-------------------------------------------+----------------------------------------------------------+
@@ -68,7 +73,7 @@
 +-------------------------------------+---------------------------+
 | Channel type                        | Measurement unit          |
 +-------------------------------------+---------------------------+
-| Acceleration on X, Y, and Z axis    | Meters per second squared |
+| Acceleration on X, Y, and Z axes    | Meters per second squared |
 +-------------------------------------+---------------------------+
 
 Sensor Events
@@ -78,8 +83,8 @@
 driver supports either none or a single active interrupt (INT) line, selectable
 from the two available options: INT1 or INT2. The active INT line should be
 specified in the device tree. If no INT line is configured, the sensor defaults
-to FIFO bypass mode, where event detection is disabled and only X, Y, and Z axis
-measurements are available.
+to FIFO bypass mode, where event detection is disabled and only individual
+X, Y, and Z axis measurements are available.
 
 The table below lists the ADXL345-related device files located in the
 device-specific path: ``/sys/bus/iio/devices/iio:deviceX/events``.
@@ -90,38 +95,52 @@
 +---------------------------------------------+---------------------------------------------+
 | Event handle                                | Description                                 |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_gesture_doubletap_en               | Enable double tap detection on all axis     |
+| in_accel_gesture_doubletap_en               | Enable double tap detection on all axes     |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_gesture_doubletap_reset_timeout    | Double tap window in [us]                   |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_gesture_doubletap_tap2_min_delay   | Double tap latent in [us]                   |
+| in_accel_gesture_doubletap_scale            | Double tap gesture threshold scale.         |
++---------------------------------------------+---------------------------------------------+
+| in_accel_gesture_doubletap_tap2_min_delay   | Double tap latency in [us]                  |
++---------------------------------------------+---------------------------------------------+
+| in_accel_gesture_doubletap_value            | Double tap threshold value                  |
++---------------------------------------------+---------------------------------------------+
+| in_accel_gesture_singletap_scale            | Single tap gesture threshold scale.         |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_gesture_singletap_timeout          | Single tap duration in [us]                 |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_gesture_singletap_value            | Single tap threshold value in 62.5/LSB      |
-+---------------------------------------------+---------------------------------------------+
-| in_accel_mag_falling_period                 | Inactivity time in seconds                  |
-+---------------------------------------------+---------------------------------------------+
-| in_accel_mag_falling_value                  | Inactivity threshold value in 62.5/LSB      |
-+---------------------------------------------+---------------------------------------------+
-| in_accel_mag_adaptive_rising_en             | Enable AC coupled activity on X axis        |
+| in_accel_gesture_singletap_value            | Single tap threshold value                  |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_mag_adaptive_falling_period        | AC coupled inactivity time in seconds       |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_mag_adaptive_falling_value         | AC coupled inactivity threshold in 62.5/LSB |
+| in_accel_mag_adaptive_falling_scale         | AC coupled inactivity threshold scale.      |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_mag_adaptive_rising_value          | AC coupled activity threshold in 62.5/LSB   |
+| in_accel_mag_adaptive_falling_value         | AC coupled inactivity threshold             |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_adaptive_rising_en             | Enable AC coupled activity on X axis        |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_adaptive_rising_scale          | AC coupled activity threshold scale.        |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_adaptive_rising_value          | AC coupled activity threshold               |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_falling_period                 | Inactivity time in seconds                  |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_falling_scale                  | DC coupled inactivity threshold scale.      |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_falling_value                  | Inactivity threshold value                  |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_mag_rising_en                      | Enable activity detection on X axis         |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_mag_rising_value                   | Activity threshold value in 62.5/LSB        |
+| in_accel_mag_rising_scale                   | DC coupled activity threshold scale.        |
++---------------------------------------------+---------------------------------------------+
+| in_accel_mag_rising_value                   | Activity threshold value                    |
++---------------------------------------------+---------------------------------------------+
+| in_accel_x&y&z_mag_adaptive_falling_en      | Enable AC coupled inactivity on all axes    |
++---------------------------------------------+---------------------------------------------+
+| in_accel_x&y&z_mag_falling_en               | Enable inactivity detection on all axes     |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_x_gesture_singletap_en             | Enable single tap detection on X axis       |
 +---------------------------------------------+---------------------------------------------+
-| in_accel_x&y&z_mag_falling_en               | Enable inactivity detection on all axis     |
-+---------------------------------------------+---------------------------------------------+
-| in_accel_x&y&z_mag_adaptive_falling_en      | Enable AC coupled inactivity on all axis    |
-+---------------------------------------------+---------------------------------------------+
 | in_accel_y_gesture_singletap_en             | Enable single tap detection on Y axis       |
 +---------------------------------------------+---------------------------------------------+
 | in_accel_z_gesture_singletap_en             | Enable single tap detection on Z axis       |
@@ -140,8 +159,8 @@
 appropriate activity and inactivity thresholds by scaling the default values
 based on the ratio of the previous range to the new one. The resulting threshold
 will never be zero and will always fall between 1 and 255, corresponding to up
-to 62.5 g/LSB as specified in the datasheet. However, you can override these
-estimated thresholds by setting explicit values.
+to 62.5 mg/LSB (0.612915 m/s^2/LSB) as specified in the datasheet. However,
+you can override these estimated thresholds by setting explicit values.
 
 When **activity** and **inactivity** events are enabled, the driver
 automatically manages hysteresis behavior by setting the **link** and
@@ -270,13 +289,13 @@
 .. code-block:: bash
 
         root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale
-        0.478899
+        0.004789
         root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale_available
-        0.478899 0.957798 1.915595 3.831190
+        0.004789 0.009578 0.019156 0.038312
 
-        root:/sys/bus/iio/devices/iio:device0> echo 1.915595 > ./in_accel_scale
+        root:/sys/bus/iio/devices/iio:device0> echo 0.019156 > ./in_accel_scale
         root:/sys/bus/iio/devices/iio:device0> cat ./in_accel_scale
-        1.915595
+        0.019156
 
 Set output data rate (ODR):
 
@@ -312,10 +331,14 @@
 
         root:/sys/bus/iio/devices/iio:device0> echo 24 > ./buffer0/length
 
-        ## AC coupled activity, threshold [62.5/LSB]
+        ## Check the event scale factor (0.0625 * 9.80665)
+        root:/sys/bus/iio/devices/iio:device0> cat ./events/in_accel_gesture_doubletap_scale
+        0.612915
+
+        ## AC coupled activity, threshold [0.612915 m/s^2/LSB]
         root:/sys/bus/iio/devices/iio:device0> echo 6 > ./events/in_accel_mag_adaptive_rising_value
 
-        ## AC coupled inactivity, threshold, [62.5/LSB]
+        ## AC coupled inactivity, threshold, [0.612915 m/s^2/LSB]
         root:/sys/bus/iio/devices/iio:device0> echo 4 > ./events/in_accel_mag_adaptive_falling_value
 
         ## AC coupled inactivity, time [s]
@@ -330,7 +353,7 @@
         ## doubletap, window [us]
         root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_reset_timeout
 
-        ## doubletap, latent [us]
+        ## doubletap, latency [us]
         root:/sys/bus/iio/devices/iio:device0> echo 0.025 > ./events/in_accel_gesture_doubletap_tap2_min_delay
 
         ## AC coupled activity, enable
diff --git a/Documentation/infiniband/index.rst b/Documentation/infiniband/index.rst
index c11049d..f57387a 100644
--- a/Documentation/infiniband/index.rst
+++ b/Documentation/infiniband/index.rst
@@ -9,7 +9,6 @@
 
    core_locking
    ipoib
-   opa_vnic
    sysfs
    tag_matching
    ucaps
diff --git a/Documentation/infiniband/opa_vnic.rst b/Documentation/infiniband/opa_vnic.rst
deleted file mode 100644
index 2f888d9..0000000
--- a/Documentation/infiniband/opa_vnic.rst
+++ /dev/null
@@ -1,159 +0,0 @@
-=================================================================
-Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC)
-=================================================================
-
-Intel Omni-Path (OPA) Virtual Network Interface Controller (VNIC) feature
-supports Ethernet functionality over Omni-Path fabric by encapsulating
-the Ethernet packets between HFI nodes.
-
-Architecture
-=============
-The patterns of exchanges of Omni-Path encapsulated Ethernet packets
-involves one or more virtual Ethernet switches overlaid on the Omni-Path
-fabric topology. A subset of HFI nodes on the Omni-Path fabric are
-permitted to exchange encapsulated Ethernet packets across a particular
-virtual Ethernet switch. The virtual Ethernet switches are logical
-abstractions achieved by configuring the HFI nodes on the fabric for
-header generation and processing. In the simplest configuration all HFI
-nodes across the fabric exchange encapsulated Ethernet packets over a
-single virtual Ethernet switch. A virtual Ethernet switch, is effectively
-an independent Ethernet network. The configuration is performed by an
-Ethernet Manager (EM) which is part of the trusted Fabric Manager (FM)
-application. HFI nodes can have multiple VNICs each connected to a
-different virtual Ethernet switch. The below diagram presents a case
-of two virtual Ethernet switches with two HFI nodes::
-
-                               +-------------------+
-                               |      Subnet/      |
-                               |     Ethernet      |
-                               |      Manager      |
-                               +-------------------+
-                                  /          /
-                                /           /
-                              /            /
-                            /             /
-  +-----------------------------+  +------------------------------+
-  |  Virtual Ethernet Switch    |  |  Virtual Ethernet Switch     |
-  |  +---------+    +---------+ |  | +---------+    +---------+   |
-  |  | VPORT   |    |  VPORT  | |  | |  VPORT  |    |  VPORT  |   |
-  +--+---------+----+---------+-+  +-+---------+----+---------+---+
-           |                 \        /                 |
-           |                   \    /                   |
-           |                     \/                     |
-           |                    /  \                    |
-           |                  /      \                  |
-       +-----------+------------+  +-----------+------------+
-       |   VNIC    |    VNIC    |  |    VNIC   |    VNIC    |
-       +-----------+------------+  +-----------+------------+
-       |          HFI           |  |          HFI           |
-       +------------------------+  +------------------------+
-
-
-The Omni-Path encapsulated Ethernet packet format is as described below.
-
-==================== ================================
-Bits                 Field
-==================== ================================
-Quad Word 0:
-0-19                 SLID (lower 20 bits)
-20-30                Length (in Quad Words)
-31                   BECN bit
-32-51                DLID (lower 20 bits)
-52-56                SC (Service Class)
-57-59                RC (Routing Control)
-60                   FECN bit
-61-62                L2 (=10, 16B format)
-63                   LT (=1, Link Transfer Head Flit)
-
-Quad Word 1:
-0-7                  L4 type (=0x78 ETHERNET)
-8-11                 SLID[23:20]
-12-15                DLID[23:20]
-16-31                PKEY
-32-47                Entropy
-48-63                Reserved
-
-Quad Word 2:
-0-15                 Reserved
-16-31                L4 header
-32-63                Ethernet Packet
-
-Quad Words 3 to N-1:
-0-63                 Ethernet packet (pad extended)
-
-Quad Word N (last):
-0-23                 Ethernet packet (pad extended)
-24-55                ICRC
-56-61                Tail
-62-63                LT (=01, Link Transfer Tail Flit)
-==================== ================================
-
-Ethernet packet is padded on the transmit side to ensure that the VNIC OPA
-packet is quad word aligned. The 'Tail' field contains the number of bytes
-padded. On the receive side the 'Tail' field is read and the padding is
-removed (along with ICRC, Tail and OPA header) before passing packet up
-the network stack.
-
-The L4 header field contains the virtual Ethernet switch id the VNIC port
-belongs to. On the receive side, this field is used to de-multiplex the
-received VNIC packets to different VNIC ports.
-
-Driver Design
-==============
-Intel OPA VNIC software design is presented in the below diagram.
-OPA VNIC functionality has a HW dependent component and a HW
-independent component.
-
-The support has been added for IB device to allocate and free the RDMA
-netdev devices. The RDMA netdev supports interfacing with the network
-stack thus creating standard network interfaces. OPA_VNIC is an RDMA
-netdev device type.
-
-The HW dependent VNIC functionality is part of the HFI1 driver. It
-implements the verbs to allocate and free the OPA_VNIC RDMA netdev.
-It involves HW resource allocation/management for VNIC functionality.
-It interfaces with the network stack and implements the required
-net_device_ops functions. It expects Omni-Path encapsulated Ethernet
-packets in the transmit path and provides HW access to them. It strips
-the Omni-Path header from the received packets before passing them up
-the network stack. It also implements the RDMA netdev control operations.
-
-The OPA VNIC module implements the HW independent VNIC functionality.
-It consists of two parts. The VNIC Ethernet Management Agent (VEMA)
-registers itself with IB core as an IB client and interfaces with the
-IB MAD stack. It exchanges the management information with the Ethernet
-Manager (EM) and the VNIC netdev. The VNIC netdev part allocates and frees
-the OPA_VNIC RDMA netdev devices. It overrides the net_device_ops functions
-set by HW dependent VNIC driver where required to accommodate any control
-operation. It also handles the encapsulation of Ethernet packets with an
-Omni-Path header in the transmit path. For each VNIC interface, the
-information required for encapsulation is configured by the EM via VEMA MAD
-interface. It also passes any control information to the HW dependent driver
-by invoking the RDMA netdev control operations::
-
-        +-------------------+ +----------------------+
-        |                   | |       Linux          |
-        |     IB MAD        | |      Network         |
-        |                   | |       Stack          |
-        +-------------------+ +----------------------+
-                 |               |          |
-                 |               |          |
-        +----------------------------+      |
-        |                            |      |
-        |      OPA VNIC Module       |      |
-        |  (OPA VNIC RDMA Netdev     |      |
-        |     & EMA functions)       |      |
-        |                            |      |
-        +----------------------------+      |
-                    |                       |
-                    |                       |
-           +------------------+             |
-           |     IB core      |             |
-           +------------------+             |
-                    |                       |
-                    |                       |
-        +--------------------------------------------+
-        |                                            |
-        |      HFI1 Driver with VNIC support         |
-        |                                            |
-        +--------------------------------------------+
diff --git a/Documentation/isdn/credits.rst b/Documentation/isdn/credits.rst
deleted file mode 100644
index 319323f..0000000
--- a/Documentation/isdn/credits.rst
+++ /dev/null
@@ -1,73 +0,0 @@
-=======
-Credits
-=======
-
-
-I want to thank all who contributed to this project and especially to:
-(in alphabetical order)
-
-Thomas Bogendörfer (tsbogend@bigbug.franken.de)
-  Tester, lots of bugfixes and hints.
-
-Alan Cox (alan@lxorguk.ukuu.org.uk)
-  For help getting into standard-kernel.
-
-Henner Eisen (eis@baty.hanse.de)
-  For X.25 implementation.
-
-Volker Götz (volker@oops.franken.de)
-  For contribution of man-pages, the imontty-tool and a perfect
-  maintaining of the mailing-list at hub-wue.
-
-Matthias Hessler (hessler@isdn4linux.de)
-  For creating and maintaining the FAQ.
-
-Bernhard Hailer (Bernhard.Hailer@lrz.uni-muenchen.de)
-  For creating the FAQ, and the leafsite HOWTO.
-
-Michael 'Ghandi' Herold (michael@abadonna.franken.de)
-  For contribution of the vbox answering machine.
-
-Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
-  For his Sync-PPP-code.
-
-Karsten Keil (keil@isdn4linux.de)
-  For adding 1TR6-support to the Teles-driver.
-  For the HiSax-driver.
-
-Michael Knigge (knick@cove.han.de)
-  For contributing the imon-tool
-
-Andreas Kool (akool@Kool.f.EUnet.de)
-  For contribution of the isdnlog/isdnrep-tool
-
-Pedro Roque Marques (roque@di.fc.ul.pt)
-  For lot of new ideas and the pcbit driver.
-
-Eberhard Mönkeberg (emoenke@gwdg.de)
-  For testing and help to get into kernel.
-
-Thomas Neumann (tn@ruhr.de)
-  For help with Cisco-SLARP and keepalive
-
-Jan den Ouden (denouden@groovin.xs4all.nl)
-  For contribution of the original teles-driver
-
-Carsten Paeth (calle@calle.in-berlin.de)
-  For the AVM-B1-CAPI2.0 driver
-
-Thomas Pfeiffer (pfeiffer@pds.de)
-  For V.110, extended T.70 and Hylafax extensions in isdn_tty.c
-
-Max Riegel (riegel@max.franken.de)
-  For making the ICN hardware-documentation and test-equipment available.
-
-Armin Schindler (mac@melware.de)
-  For the eicon active card driver.
-
-Gerhard 'Fido' Schneider (fido@wuff.mayn.de)
-  For heavy-duty-beta-testing with his BBS ;)
-
-Thomas Uhl (uhl@think.de)
-  For distributing the cards.
-  For pushing me to work ;-)
diff --git a/Documentation/isdn/index.rst b/Documentation/isdn/index.rst
deleted file mode 100644
index d1125a1..0000000
--- a/Documentation/isdn/index.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-====
-ISDN
-====
-
-.. toctree::
-   :maxdepth: 2
-
-   interface_capi
-
-   m_isdn
-
-   credits
diff --git a/Documentation/isdn/interface_capi.rst b/Documentation/isdn/interface_capi.rst
deleted file mode 100644
index 4d63b34..0000000
--- a/Documentation/isdn/interface_capi.rst
+++ /dev/null
@@ -1,336 +0,0 @@
-=========================================
-Kernel CAPI Interface to Hardware Drivers
-=========================================
-
-1. Overview
-===========
-
-From the CAPI 2.0 specification:
-COMMON-ISDN-API (CAPI) is an application programming interface standard used
-to access ISDN equipment connected to basic rate interfaces (BRI) and primary
-rate interfaces (PRI).
-
-Kernel CAPI operates as a dispatching layer between CAPI applications and CAPI
-hardware drivers. Hardware drivers register ISDN devices (controllers, in CAPI
-lingo) with Kernel CAPI to indicate their readiness to provide their service
-to CAPI applications. CAPI applications also register with Kernel CAPI,
-requesting association with a CAPI device. Kernel CAPI then dispatches the
-application registration to an available device, forwarding it to the
-corresponding hardware driver. Kernel CAPI then forwards CAPI messages in both
-directions between the application and the hardware driver.
-
-Format and semantics of CAPI messages are specified in the CAPI 2.0 standard.
-This standard is freely available from https://www.capi.org.
-
-
-2. Driver and Device Registration
-=================================
-
-CAPI drivers must register each of the ISDN devices they control with Kernel
-CAPI by calling the Kernel CAPI function attach_capi_ctr() with a pointer to a
-struct capi_ctr before they can be used. This structure must be filled with
-the names of the driver and controller, and a number of callback function
-pointers which are subsequently used by Kernel CAPI for communicating with the
-driver. The registration can be revoked by calling the function
-detach_capi_ctr() with a pointer to the same struct capi_ctr.
-
-Before the device can be actually used, the driver must fill in the device
-information fields 'manu', 'version', 'profile' and 'serial' in the capi_ctr
-structure of the device, and signal its readiness by calling capi_ctr_ready().
-From then on, Kernel CAPI may call the registered callback functions for the
-device.
-
-If the device becomes unusable for any reason (shutdown, disconnect ...), the
-driver has to call capi_ctr_down(). This will prevent further calls to the
-callback functions by Kernel CAPI.
-
-
-3. Application Registration and Communication
-=============================================
-
-Kernel CAPI forwards registration requests from applications (calls to CAPI
-operation CAPI_REGISTER) to an appropriate hardware driver by calling its
-register_appl() callback function. A unique Application ID (ApplID, u16) is
-allocated by Kernel CAPI and passed to register_appl() along with the
-parameter structure provided by the application. This is analogous to the
-open() operation on regular files or character devices.
-
-After a successful return from register_appl(), CAPI messages from the
-application may be passed to the driver for the device via calls to the
-send_message() callback function. Conversely, the driver may call Kernel
-CAPI's capi_ctr_handle_message() function to pass a received CAPI message to
-Kernel CAPI for forwarding to an application, specifying its ApplID.
-
-Deregistration requests (CAPI operation CAPI_RELEASE) from applications are
-forwarded as calls to the release_appl() callback function, passing the same
-ApplID as with register_appl(). After return from release_appl(), no CAPI
-messages for that application may be passed to or from the device anymore.
-
-
-4. Data Structures
-==================
-
-4.1 struct capi_driver
-----------------------
-
-This structure describes a Kernel CAPI driver itself. It is used in the
-register_capi_driver() and unregister_capi_driver() functions, and contains
-the following non-private fields, all to be set by the driver before calling
-register_capi_driver():
-
-``char name[32]``
-	the name of the driver, as a zero-terminated ASCII string
-``char revision[32]``
-	the revision number of the driver, as a zero-terminated ASCII string
-
-4.2 struct capi_ctr
--------------------
-
-This structure describes an ISDN device (controller) handled by a Kernel CAPI
-driver. After registration via the attach_capi_ctr() function it is passed to
-all controller specific lower layer interface and callback functions to
-identify the controller to operate on.
-
-It contains the following non-private fields:
-
-to be set by the driver before calling attach_capi_ctr():
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``struct module *owner``
-	pointer to the driver module owning the device
-
-``void *driverdata``
-	an opaque pointer to driver specific data, not touched by Kernel CAPI
-
-``char name[32]``
-	the name of the controller, as a zero-terminated ASCII string
-
-``char *driver_name``
-	the name of the driver, as a zero-terminated ASCII string
-
-``int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)``
-	(optional) pointer to a callback function for sending firmware and
-	configuration data to the device
-
-	The function may return before the operation has completed.
-
-	Completion must be signalled by a call to capi_ctr_ready().
-
-	Return value: 0 on success, error code on error
-	Called in process context.
-
-``void (*reset_ctr)(struct capi_ctr *ctrlr)``
-	(optional) pointer to a callback function for stopping the device,
-	releasing all registered applications
-
-	The function may return before the operation has completed.
-
-	Completion must be signalled by a call to capi_ctr_down().
-
-	Called in process context.
-
-``void (*register_appl)(struct capi_ctr *ctrlr, u16 applid, capi_register_params *rparam)``
-	pointers to callback function for registration of
-	applications with the device
-
-	Calls to these functions are serialized by Kernel CAPI so that only
-	one call to any of them is active at any time.
-
-``void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)``
-	pointers to callback functions deregistration of
-	applications with the device
-
-	Calls to these functions are serialized by Kernel CAPI so that only
-	one call to any of them is active at any time.
-
-``u16  (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)``
-	pointer to a callback function for sending a CAPI message to the
-	device
-
-	Return value: CAPI error code
-
-	If the method returns 0 (CAPI_NOERROR) the driver has taken ownership
-	of the skb and the caller may no longer access it. If it returns a
-	non-zero (error) value then ownership of the skb returns to the caller
-	who may reuse or free it.
-
-	The return value should only be used to signal problems with respect
-	to accepting or queueing the message. Errors occurring during the
-	actual processing of the message should be signaled with an
-	appropriate reply message.
-
-	May be called in process or interrupt context.
-
-	Calls to this function are not serialized by Kernel CAPI, ie. it must
-	be prepared to be re-entered.
-
-``char *(*procinfo)(struct capi_ctr *ctrlr)``
-	pointer to a callback function returning the entry for the device in
-	the CAPI controller info table, /proc/capi/controller
-
-Note:
-  Callback functions except send_message() are never called in interrupt
-  context.
-
-to be filled in before calling capi_ctr_ready():
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``u8 manu[CAPI_MANUFACTURER_LEN]``
-	value to return for CAPI_GET_MANUFACTURER
-
-``capi_version version``
-	value to return for CAPI_GET_VERSION
-
-``capi_profile profile``
-	value to return for CAPI_GET_PROFILE
-
-``u8 serial[CAPI_SERIAL_LEN]``
-	value to return for CAPI_GET_SERIAL
-
-
-4.3 SKBs
---------
-
-CAPI messages are passed between Kernel CAPI and the driver via send_message()
-and capi_ctr_handle_message(), stored in the data portion of a socket buffer
-(skb).  Each skb contains a single CAPI message coded according to the CAPI 2.0
-standard.
-
-For the data transfer messages, DATA_B3_REQ and DATA_B3_IND, the actual
-payload data immediately follows the CAPI message itself within the same skb.
-The Data and Data64 parameters are not used for processing. The Data64
-parameter may be omitted by setting the length field of the CAPI message to 22
-instead of 30.
-
-
-4.4 The _cmsg Structure
------------------------
-
-(declared in <linux/isdn/capiutil.h>)
-
-The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
-accessible form. It contains members for all possible CAPI 2.0 parameters,
-including subparameters of the Additional Info and B Protocol structured
-parameters, with the following exceptions:
-
-* second Calling party number (CONNECT_IND)
-
-* Data64 (DATA_B3_REQ and DATA_B3_IND)
-
-* Sending complete (subparameter of Additional Info, CONNECT_REQ and INFO_REQ)
-
-* Global Configuration (subparameter of B Protocol, CONNECT_REQ, CONNECT_RESP
-  and SELECT_B_PROTOCOL_REQ)
-
-Only those parameters appearing in the message type currently being processed
-are actually used. Unused members should be set to zero.
-
-Members are named after the CAPI 2.0 standard names of the parameters they
-represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
-types are:
-
-=========== =================================================================
-u8          for CAPI parameters of type 'byte'
-
-u16         for CAPI parameters of type 'word'
-
-u32         for CAPI parameters of type 'dword'
-
-_cstruct    for CAPI parameters of type 'struct'
-	    The member is a pointer to a buffer containing the parameter in
-	    CAPI encoding (length + content). It may also be NULL, which will
-	    be taken to represent an empty (zero length) parameter.
-	    Subparameters are stored in encoded form within the content part.
-
-_cmstruct   alternative representation for CAPI parameters of type 'struct'
-	    (used only for the 'Additional Info' and 'B Protocol' parameters)
-	    The representation is a single byte containing one of the values:
-	    CAPI_DEFAULT: The parameter is empty/absent.
-	    CAPI_COMPOSE: The parameter is present.
-	    Subparameter values are stored individually in the corresponding
-	    _cmsg structure members.
-=========== =================================================================
-
-
-5. Lower Layer Interface Functions
-==================================
-
-::
-
-  int attach_capi_ctr(struct capi_ctr *ctrlr)
-  int detach_capi_ctr(struct capi_ctr *ctrlr)
-
-register/unregister a device (controller) with Kernel CAPI
-
-::
-
-  void capi_ctr_ready(struct capi_ctr *ctrlr)
-  void capi_ctr_down(struct capi_ctr *ctrlr)
-
-signal controller ready/not ready
-
-::
-
-  void capi_ctr_handle_message(struct capi_ctr * ctrlr, u16 applid,
-			       struct sk_buff *skb)
-
-pass a received CAPI message to Kernel CAPI
-for forwarding to the specified application
-
-
-6. Helper Functions and Macros
-==============================
-
-Macros to extract/set element values from/in a CAPI message header
-(from <linux/isdn/capiutil.h>):
-
-======================  =============================   ====================
-Get Macro		Set Macro			Element (Type)
-======================  =============================   ====================
-CAPIMSG_LEN(m)		CAPIMSG_SETLEN(m, len)		Total Length (u16)
-CAPIMSG_APPID(m)	CAPIMSG_SETAPPID(m, applid)	ApplID (u16)
-CAPIMSG_COMMAND(m)	CAPIMSG_SETCOMMAND(m,cmd)	Command (u8)
-CAPIMSG_SUBCOMMAND(m)	CAPIMSG_SETSUBCOMMAND(m, cmd)	Subcommand (u8)
-CAPIMSG_CMD(m)		-				Command*256
-							+ Subcommand (u16)
-CAPIMSG_MSGID(m)	CAPIMSG_SETMSGID(m, msgid)	Message Number (u16)
-
-CAPIMSG_CONTROL(m)	CAPIMSG_SETCONTROL(m, contr)	Controller/PLCI/NCCI
-							(u32)
-CAPIMSG_DATALEN(m)	CAPIMSG_SETDATALEN(m, len)	Data Length (u16)
-======================  =============================   ====================
-
-
-Library functions for working with _cmsg structures
-(from <linux/isdn/capiutil.h>):
-
-``char *capi_cmd2str(u8 Command, u8 Subcommand)``
-	Returns the CAPI 2.0 message name corresponding to the given command
-	and subcommand values, as a static ASCII string. The return value may
-	be NULL if the command/subcommand is not one of those defined in the
-	CAPI 2.0 standard.
-
-
-7. Debugging
-============
-
-The module kernelcapi has a module parameter showcapimsgs controlling some
-debugging output produced by the module. It can only be set when the module is
-loaded, via a parameter "showcapimsgs=<n>" to the modprobe command, either on
-the command line or in the configuration file.
-
-If the lowest bit of showcapimsgs is set, kernelcapi logs controller and
-application up and down events.
-
-In addition, every registered CAPI controller has an associated traceflag
-parameter controlling how CAPI messages sent from and to the controller are
-logged. The traceflag parameter is initialized with the value of the
-showcapimsgs parameter when the controller is registered, but can later be
-changed via the MANUFACTURER_REQ command KCAPI_CMD_TRACE.
-
-If the value of traceflag is non-zero, CAPI messages are logged.
-DATA_B3 messages are only logged if the value of traceflag is > 2.
-
-If the lowest bit of traceflag is set, only the command/subcommand and message
-length are logged. Otherwise, kernelcapi logs a readable representation of
-the entire message.
diff --git a/Documentation/isdn/m_isdn.rst b/Documentation/isdn/m_isdn.rst
deleted file mode 100644
index 5847a16..0000000
--- a/Documentation/isdn/m_isdn.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-============
-mISDN Driver
-============
-
-mISDN is a new modular ISDN driver, in the long term it should replace
-the old I4L driver architecture for passive ISDN cards.
-It was designed to allow a broad range of applications and interfaces
-but only have the basic function in kernel, the interface to the user
-space is based on sockets with a own address family AF_ISDN.
diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/specs/nfsd.yaml
index f87b5a0..8ab43c8 100644
--- a/Documentation/netlink/specs/nfsd.yaml
+++ b/Documentation/netlink/specs/nfsd.yaml
@@ -81,6 +81,11 @@
       -
         name: min-threads
         type: u32
+      -
+        name: fh-key
+        type: binary
+        checks:
+            exact-len: 16
   -
     name: version
     attributes:
@@ -163,6 +168,7 @@
             - leasetime
             - scope
             - min-threads
+            - fh-key
     -
       name: threads-get
       doc: get the maximum number of running threads
diff --git a/Documentation/networking/6pack.rst b/Documentation/networking/6pack.rst
deleted file mode 100644
index 66d5fd4..0000000
--- a/Documentation/networking/6pack.rst
+++ /dev/null
@@ -1,191 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==============
-6pack Protocol
-==============
-
-This is the 6pack-mini-HOWTO, written by
-
-Andreas Könsgen DG3KQ
-
-:Internet: ajk@comnets.uni-bremen.de
-:AMPR-net: dg3kq@db0pra.ampr.org
-:AX.25:    dg3kq@db0ach.#nrw.deu.eu
-
-Last update: April 7, 1998
-
-1. What is 6pack, and what are the advantages to KISS?
-======================================================
-
-6pack is a transmission protocol for data exchange between the PC and
-the TNC over a serial line. It can be used as an alternative to KISS.
-
-6pack has two major advantages:
-
-- The PC is given full control over the radio
-  channel. Special control data is exchanged between the PC and the TNC so
-  that the PC knows at any time if the TNC is receiving data, if a TNC
-  buffer underrun or overrun has occurred, if the PTT is
-  set and so on. This control data is processed at a higher priority than
-  normal data, so a data stream can be interrupted at any time to issue an
-  important event. This helps to improve the channel access and timing
-  algorithms as everything is computed in the PC. It would even be possible
-  to experiment with something completely different from the known CSMA and
-  DAMA channel access methods.
-  This kind of real-time control is especially important to supply several
-  TNCs that are connected between each other and the PC by a daisy chain
-  (however, this feature is not supported yet by the Linux 6pack driver).
-
-- Each packet transferred over the serial line is supplied with a checksum,
-  so it is easy to detect errors due to problems on the serial line.
-  Received packets that are corrupt are not passed on to the AX.25 layer.
-  Damaged packets that the TNC has received from the PC are not transmitted.
-
-More details about 6pack are described in the file 6pack.ps that is located
-in the doc directory of the AX.25 utilities package.
-
-2. Who has developed the 6pack protocol?
-========================================
-
-The 6pack protocol has been developed by Ekki Plicht DF4OR, Henning Rech
-DF9IC and Gunter Jost DK7WJ. A driver for 6pack, written by Gunter Jost and
-Matthias Welwarsky DG2FEF, comes along with the PC version of FlexNet.
-They have also written a firmware for TNCs to perform the 6pack
-protocol (see section 4 below).
-
-3. Where can I get the latest version of 6pack for LinuX?
-=========================================================
-
-At the moment, the 6pack stuff can obtained via anonymous ftp from
-db0bm.automation.fh-aachen.de. In the directory /incoming/dg3kq,
-there is a file named 6pack.tgz.
-
-4. Preparing the TNC for 6pack operation
-========================================
-
-To be able to use 6pack, a special firmware for the TNC is needed. The EPROM
-of a newly bought TNC does not contain 6pack, so you will have to
-program an EPROM yourself. The image file for 6pack EPROMs should be
-available on any packet radio box where PC/FlexNet can be found. The name of
-the file is 6pack.bin. This file is copyrighted and maintained by the FlexNet
-team. It can be used under the terms of the license that comes along
-with PC/FlexNet. Please do not ask me about the internals of this file as I
-don't know anything about it. I used a textual description of the 6pack
-protocol to program the Linux driver.
-
-TNCs contain a 64kByte EPROM, the lower half of which is used for
-the firmware/KISS. The upper half is either empty or is sometimes
-programmed with software called TAPR. In the latter case, the TNC
-is supplied with a DIP switch so you can easily change between the
-two systems. When programming a new EPROM, one of the systems is replaced
-by 6pack. It is useful to replace TAPR, as this software is rarely used
-nowadays. If your TNC is not equipped with the switch mentioned above, you
-can build in one yourself that switches over the highest address pin
-of the EPROM between HIGH and LOW level. After having inserted the new EPROM
-and switched to 6pack, apply power to the TNC for a first test. The connect
-and the status LED are lit for about a second if the firmware initialises
-the TNC correctly.
-
-5. Building and installing the 6pack driver
-===========================================
-
-The driver has been tested with kernel version 2.1.90. Use with older
-kernels may lead to a compilation error because the interface to a kernel
-function has been changed in the 2.1.8x kernels.
-
-How to turn on 6pack support:
------------------------------
-
-- In the linux kernel configuration program, select the code maturity level
-  options menu and turn on the prompting for development drivers.
-
-- Select the amateur radio support menu and turn on the serial port 6pack
-  driver.
-
-- Compile and install the kernel and the modules.
-
-To use the driver, the kissattach program delivered with the AX.25 utilities
-has to be modified.
-
-- Do a cd to the directory that holds the kissattach sources. Edit the
-  kissattach.c file. At the top, insert the following lines::
-
-    #ifndef N_6PACK
-    #define N_6PACK (N_AX25+1)
-    #endif
-
-  Then find the line:
-
-    int disc = N_AX25;
-
-  and replace N_AX25 by N_6PACK.
-
-- Recompile kissattach. Rename it to spattach to avoid confusions.
-
-Installing the driver:
-----------------------
-
-- Do an insmod 6pack. Look at your /var/log/messages file to check if the
-  module has printed its initialization message.
-
-- Do a spattach as you would launch kissattach when starting a KISS port.
-  Check if the kernel prints the message '6pack: TNC found'.
-
-- From here, everything should work as if you were setting up a KISS port.
-  The only difference is that the network device that represents
-  the 6pack port is called sp instead of sl or ax. So, sp0 would be the
-  first 6pack port.
-
-Although the driver has been tested on various platforms, I still declare it
-ALPHA. BE CAREFUL! Sync your disks before insmoding the 6pack module
-and spattaching. Watch out if your computer behaves strangely. Read section
-6 of this file about known problems.
-
-Note that the connect and status LEDs of the TNC are controlled in a
-different way than they are when the TNC is used with PC/FlexNet. When using
-FlexNet, the connect LED is on if there is a connection; the status LED is
-on if there is data in the buffer of the PC's AX.25 engine that has to be
-transmitted. Under Linux, the 6pack layer is beyond the AX.25 layer,
-so the 6pack driver doesn't know anything about connects or data that
-has not yet been transmitted. Therefore the LEDs are controlled
-as they are in KISS mode: The connect LED is turned on if data is transferred
-from the PC to the TNC over the serial line, the status LED if data is
-sent to the PC.
-
-6. Known problems
-=================
-
-When testing the driver with 2.0.3x kernels and
-operating with data rates on the radio channel of 9600 Baud or higher,
-the driver may, on certain systems, sometimes print the message '6pack:
-bad checksum', which is due to data loss if the other station sends two
-or more subsequent packets. I have been told that this is due to a problem
-with the serial driver of 2.0.3x kernels. I don't know yet if the problem
-still exists with 2.1.x kernels, as I have heard that the serial driver
-code has been changed with 2.1.x.
-
-When shutting down the sp interface with ifconfig, the kernel crashes if
-there is still an AX.25 connection left over which an IP connection was
-running, even if that IP connection is already closed. The problem does not
-occur when there is a bare AX.25 connection still running. I don't know if
-this is a problem of the 6pack driver or something else in the kernel.
-
-The driver has been tested as a module, not yet as a kernel-builtin driver.
-
-The 6pack protocol supports daisy-chaining of TNCs in a token ring, which is
-connected to one serial port of the PC. This feature is not implemented
-and at least at the moment I won't be able to do it because I do not have
-the opportunity to build a TNC daisy-chain and test it.
-
-Some of the comments in the source code are inaccurate. They are left from
-the SLIP/KISS driver, from which the 6pack driver has been derived.
-I haven't modified or removed them yet -- sorry! The code itself needs
-some cleaning and optimizing. This will be done in a later release.
-
-If you encounter a bug or if you have a question or suggestion concerning the
-driver, feel free to mail me, using the addresses given at the beginning of
-this file.
-
-Have fun!
-
-Andreas
diff --git a/Documentation/networking/ax25.rst b/Documentation/networking/ax25.rst
deleted file mode 100644
index 89c79dd..0000000
--- a/Documentation/networking/ax25.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=====
-AX.25
-=====
-
-To use the amateur radio protocols within Linux you will need to get a
-suitable copy of the AX.25 Utilities. More detailed information about
-AX.25, NET/ROM and ROSE, associated programs and utilities can be
-found on https://linux-ax25.in-berlin.de.
-
-There is a mailing list for discussing Linux amateur radio matters
-called linux-hams@vger.kernel.org. To subscribe to it, send a message to
-linux-hams+subscribe@vger.kernel.org or use the web interface at
-https://vger.kernel.org. The subject and body of the message are
-ignored.  You don't need to be subscribed to post but of course that
-means you might miss an answer.
diff --git a/Documentation/networking/caif/caif.rst b/Documentation/networking/caif/caif.rst
deleted file mode 100644
index d922d41..0000000
--- a/Documentation/networking/caif/caif.rst
+++ /dev/null
@@ -1,138 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-
-================
-Using Linux CAIF
-================
-
-
-:Copyright: |copy| ST-Ericsson AB 2010
-
-:Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
-
-Start
-=====
-
-If you have compiled CAIF for modules do::
-
-    $modprobe crc_ccitt
-    $modprobe caif
-    $modprobe caif_socket
-    $modprobe chnl_net
-
-
-Preparing the setup with a STE modem
-====================================
-
-If you are working on integration of CAIF you should make sure
-that the kernel is built with module support.
-
-There are some things that need to be tweaked to get the host TTY correctly
-set up to talk to the modem.
-Since the CAIF stack is running in the kernel and we want to use the existing
-TTY, we are installing our physical serial driver as a line discipline above
-the TTY device.
-
-To achieve this we need to install the N_CAIF ldisc from user space.
-The benefit is that we can hook up to any TTY.
-
-The use of Start-of-frame-extension (STX) must also be set as
-module parameter "ser_use_stx".
-
-Normally Frame Checksum is always used on UART, but this is also provided as a
-module parameter "ser_use_fcs".
-
-::
-
-    $ modprobe caif_serial ser_ttyname=/dev/ttyS0 ser_use_stx=yes
-    $ ifconfig caif_ttyS0 up
-
-PLEASE NOTE:
-		There is a limitation in Android shell.
-		It only accepts one argument to insmod/modprobe!
-
-Trouble shooting
-================
-
-There are debugfs parameters provided for serial communication.
-/sys/kernel/debug/caif_serial/<tty-name>/
-
-* ser_state:   Prints the bit-mask status where
-
-  - 0x02 means SENDING, this is a transient state.
-  - 0x10 means FLOW_OFF_SENT, i.e. the previous frame has not been sent
-    and is blocking further send operation. Flow OFF has been propagated
-    to all CAIF Channels using this TTY.
-
-* tty_status: Prints the bit-mask tty status information
-
-  - 0x01 - tty->warned is on.
-  - 0x04 - tty->packed is on.
-  - 0x08 - tty->flow.tco_stopped is on.
-  - 0x10 - tty->hw_stopped is on.
-  - 0x20 - tty->flow.stopped is on.
-
-* last_tx_msg: Binary blob Prints the last transmitted frame.
-
-  This can be printed with::
-
-	$od --format=x1 /sys/kernel/debug/caif_serial/<tty>/last_rx_msg.
-
-  The first two tx messages sent look like this. Note: The initial
-  byte 02 is start of frame extension (STX) used for re-syncing
-  upon errors.
-
-  - Enumeration::
-
-        0000000  02 05 00 00 03 01 d2 02
-                 |  |     |  |  |  |
-                 STX(1)   |  |  |  |
-                    Length(2)|  |  |
-                          Control Channel(1)
-                             Command:Enumeration(1)
-                                Link-ID(1)
-                                    Checksum(2)
-
-  - Channel Setup::
-
-        0000000  02 07 00 00 00 21 a1 00 48 df
-                 |  |     |  |  |  |  |  |
-                 STX(1)   |  |  |  |  |  |
-                    Length(2)|  |  |  |  |
-                          Control Channel(1)
-                             Command:Channel Setup(1)
-                                Channel Type(1)
-                                    Priority and Link-ID(1)
-				      Endpoint(1)
-					  Checksum(2)
-
-* last_rx_msg: Prints the last transmitted frame.
-
-  The RX messages for LinkSetup look almost identical but they have the
-  bit 0x20 set in the command bit, and Channel Setup has added one byte
-  before Checksum containing Channel ID.
-
-  NOTE:
-	Several CAIF Messages might be concatenated. The maximum debug
-	buffer size is 128 bytes.
-
-Error Scenarios
-===============
-
-- last_tx_msg contains channel setup message and last_rx_msg is empty ->
-  The host seems to be able to send over the UART, at least the CAIF ldisc get
-  notified that sending is completed.
-
-- last_tx_msg contains enumeration message and last_rx_msg is empty ->
-  The host is not able to send the message from UART, the tty has not been
-  able to complete the transmit operation.
-
-- if /sys/kernel/debug/caif_serial/<tty>/tty_status is non-zero there
-  might be problems transmitting over UART.
-
-  E.g. host and modem wiring is not correct you will typically see
-  tty_status = 0x10 (hw_stopped) and ser_state = 0x10 (FLOW_OFF_SENT).
-
-  You will probably see the enumeration message in last_tx_message
-  and empty last_rx_message.
diff --git a/Documentation/networking/caif/index.rst b/Documentation/networking/caif/index.rst
deleted file mode 100644
index ec29b6f..0000000
--- a/Documentation/networking/caif/index.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-CAIF
-====
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   linux_caif
-   caif
diff --git a/Documentation/networking/caif/linux_caif.rst b/Documentation/networking/caif/linux_caif.rst
deleted file mode 100644
index a048086..0000000
--- a/Documentation/networking/caif/linux_caif.rst
+++ /dev/null
@@ -1,195 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-==========
-Linux CAIF
-==========
-
-Copyright |copy| ST-Ericsson AB 2010
-
-:Author: Sjur Brendeland/ sjur.brandeland@stericsson.com
-:License terms: GNU General Public License (GPL) version 2
-
-
-Introduction
-============
-
-CAIF is a MUX protocol used by ST-Ericsson cellular modems for
-communication between Modem and host. The host processes can open virtual AT
-channels, initiate GPRS Data connections, Video channels and Utility Channels.
-The Utility Channels are general purpose pipes between modem and host.
-
-ST-Ericsson modems support a number of transports between modem
-and host. Currently, UART and Loopback are available for Linux.
-
-
-Architecture
-============
-
-The implementation of CAIF is divided into:
-
-* CAIF Socket Layer and GPRS IP Interface.
-* CAIF Core Protocol Implementation
-* CAIF Link Layer, implemented as NET devices.
-
-::
-
-  RTNL
-   !
-   !	      +------+	 +------+
-   !	     +------+!	+------+!
-   !	     !	IP  !!	!Socket!!
-   +-------> !interf!+	! API  !+	<- CAIF Client APIs
-   !	     +------+	+------!
-   !		!	    !
-   !		+-----------+
-   !		      !
-   !		   +------+		<- CAIF Core Protocol
-   !		   ! CAIF !
-   !		   ! Core !
-   !		   +------+
-   !	   +----------!---------+
-   !	   !	      !		!
-   !	+------+   +-----+   +------+
-   +--> ! HSI  !   ! TTY !   ! USB  !	<- Link Layer (Net Devices)
-	+------+   +-----+   +------+
-
-
-
-Implementation
-==============
-
-
-CAIF Core Protocol Layer
-------------------------
-
-CAIF Core layer implements the CAIF protocol as defined by ST-Ericsson.
-It implements the CAIF protocol stack in a layered approach, where
-each layer described in the specification is implemented as a separate layer.
-The architecture is inspired by the design patterns "Protocol Layer" and
-"Protocol Packet".
-
-CAIF structure
-^^^^^^^^^^^^^^
-
-The Core CAIF implementation contains:
-
-      -	Simple implementation of CAIF.
-      -	Layered architecture (a la Streams), each layer in the CAIF
-	specification is implemented in a separate c-file.
-      -	Clients must call configuration function to add PHY layer.
-      -	Clients must implement CAIF layer to consume/produce
-	CAIF payload with receive and transmit functions.
-      -	Clients must call configuration function to add and connect the
-	Client layer.
-      - When receiving / transmitting CAIF Packets (cfpkt), ownership is passed
-	to the called function (except for framing layers' receive function)
-
-Layered Architecture
-====================
-
-The CAIF protocol can be divided into two parts: Support functions and Protocol
-Implementation. The support functions include:
-
-      - CFPKT CAIF Packet. Implementation of CAIF Protocol Packet. The
-	CAIF Packet has functions for creating, destroying and adding content
-	and for adding/extracting header and trailers to protocol packets.
-
-The CAIF Protocol implementation contains:
-
-      - CFCNFG CAIF Configuration layer. Configures the CAIF Protocol
-	Stack and provides a Client interface for adding Link-Layer and
-	Driver interfaces on top of the CAIF Stack.
-
-      - CFCTRL CAIF Control layer. Encodes and Decodes control messages
-	such as enumeration and channel setup. Also matches request and
-	response messages.
-
-      - CFSERVL General CAIF Service Layer functionality; handles flow
-	control and remote shutdown requests.
-
-      - CFVEI CAIF VEI layer. Handles CAIF AT Channels on VEI (Virtual
-	External Interface). This layer encodes/decodes VEI frames.
-
-      - CFDGML CAIF Datagram layer. Handles CAIF Datagram layer (IP
-	traffic), encodes/decodes Datagram frames.
-
-      - CFMUX CAIF Mux layer. Handles multiplexing between multiple
-	physical bearers and multiple channels such as VEI, Datagram, etc.
-	The MUX keeps track of the existing CAIF Channels and
-	Physical Instances and selects the appropriate instance based
-	on Channel-Id and Physical-ID.
-
-      - CFFRML CAIF Framing layer. Handles Framing i.e. Frame length
-	and frame checksum.
-
-      - CFSERL CAIF Serial layer. Handles concatenation/split of frames
-	into CAIF Frames with correct length.
-
-::
-
-		    +---------+
-		    | Config  |
-		    | CFCNFG  |
-		    +---------+
-			 !
-    +---------+	    +---------+	    +---------+
-    |	AT    |	    | Control |	    | Datagram|
-    | CFVEIL  |	    | CFCTRL  |	    | CFDGML  |
-    +---------+	    +---------+	    +---------+
-	   \_____________!______________/
-			 !
-		    +---------+
-		    |	MUX   |
-		    |	      |
-		    +---------+
-		    _____!_____
-		   /	       \
-	    +---------+	    +---------+
-	    | CFFRML  |	    | CFFRML  |
-	    | Framing |	    | Framing |
-	    +---------+	    +---------+
-		 !		!
-	    +---------+	    +---------+
-	    |	      |	    | Serial  |
-	    |	      |	    | CFSERL  |
-	    +---------+	    +---------+
-
-
-In this layered approach the following "rules" apply.
-
-      - All layers embed the same structure "struct cflayer"
-      - A layer does not depend on any other layer's private data.
-      - Layers are stacked by setting the pointers::
-
-		  layer->up , layer->dn
-
-      -	In order to send data upwards, each layer should do::
-
-		 layer->up->receive(layer->up, packet);
-
-      - In order to send data downwards, each layer should do::
-
-		 layer->dn->transmit(layer->dn, packet);
-
-
-CAIF Socket and IP interface
-============================
-
-The IP interface and CAIF socket API are implemented on top of the
-CAIF Core protocol. The IP Interface and CAIF socket have an instance of
-'struct cflayer', just like the CAIF Core protocol stack.
-Net device and Socket implement the 'receive()' function defined by
-'struct cflayer', just like the rest of the CAIF stack. In this way, transmit and
-receive of packets is handled as by the rest of the layers: the 'dn->transmit()'
-function is called in order to transmit data.
-
-Configuration of Link Layer
----------------------------
-The Link Layer is implemented as Linux network devices (struct net_device).
-Payload handling and registration is done using standard Linux mechanisms.
-
-The CAIF Protocol relies on a loss-less link layer without implementing
-retransmission. This implies that packet drops must not happen.
-Therefore a flow-control mechanism is implemented where the physical
-interface can initiate flow stop for all CAIF Channels.
diff --git a/Documentation/networking/device_drivers/atm/fore200e.rst b/Documentation/networking/device_drivers/atm/fore200e.rst
deleted file mode 100644
index 55df9ec..0000000
--- a/Documentation/networking/device_drivers/atm/fore200e.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=============================================
-FORE Systems PCA-200E/SBA-200E ATM NIC driver
-=============================================
-
-This driver adds support for the FORE Systems 200E-series ATM adapters
-to the Linux operating system. It is based on the earlier PCA-200E driver
-written by Uwe Dannowski.
-
-The driver simultaneously supports PCA-200E and SBA-200E adapters on
-i386, alpha (untested), powerpc, sparc and sparc64 archs.
-
-The intent is to enable the use of different models of FORE adapters at the
-same time, by hosts that have several bus interfaces (such as PCI+SBUS,
-or PCI+EISA).
-
-Only PCI and SBUS devices are currently supported by the driver, but support
-for other bus interfaces such as EISA should not be too hard to add.
-
-
-Firmware Copyright Notice
--------------------------
-
-Please read the fore200e_firmware_copyright file present
-in the linux/drivers/atm directory for details and restrictions.
-
-
-Firmware Updates
-----------------
-
-The FORE Systems 200E-series driver is shipped with firmware data being
-uploaded to the ATM adapters at system boot time or at module loading time.
-The supplied firmware images should work with all adapters.
-
-However, if you encounter problems (the firmware doesn't start or the driver
-is unable to read the PROM data), you may consider trying another firmware
-version. Alternative binary firmware images can be found somewhere on the
-ForeThought CD-ROM supplied with your adapter by FORE Systems.
-
-You can also get the latest firmware images from FORE Systems at
-https://en.wikipedia.org/wiki/FORE_Systems. Register TACTics Online and go to
-the 'software updates' pages. The firmware binaries are part of
-the various ForeThought software distributions.
-
-Notice that different versions of the PCA-200E firmware exist, depending
-on the endianness of the host architecture. The driver is shipped with
-both little and big endian PCA firmware images.
-
-Name and location of the new firmware images can be set at kernel
-configuration time:
-
-1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix)
-   to some directory, such as linux/drivers/atm.
-
-2. Reconfigure your kernel to set the new firmware name and location.
-   Expected pathnames are absolute or relative to the drivers/atm directory.
-
-3. Rebuild and re-install your kernel or your module.
-
-
-Feedback
---------
-
-Feedback is welcome. Please send success stories/bug reports/
-patches/improvement/comments/flames to <lizzi@cnam.fr>.
diff --git a/Documentation/networking/device_drivers/atm/index.rst b/Documentation/networking/device_drivers/atm/index.rst
index 724552c..9392c86f 100644
--- a/Documentation/networking/device_drivers/atm/index.rst
+++ b/Documentation/networking/device_drivers/atm/index.rst
@@ -9,5 +9,3 @@
    :maxdepth: 2
 
    cxacru
-   fore200e
-   iphase
diff --git a/Documentation/networking/device_drivers/atm/iphase.rst b/Documentation/networking/device_drivers/atm/iphase.rst
deleted file mode 100644
index 388c710..0000000
--- a/Documentation/networking/device_drivers/atm/iphase.rst
+++ /dev/null
@@ -1,193 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-==================================
-ATM (i)Chip IA Linux Driver Source
-==================================
-
-			      READ ME FIRST
-
---------------------------------------------------------------------------------
-
-		     Read This Before You Begin!
-
---------------------------------------------------------------------------------
-
-Description
-===========
-
-This is the README file for the Interphase PCI ATM (i)Chip IA Linux driver
-source release.
-
-The features and limitations of this driver are as follows:
-
-    - A single VPI (VPI value of 0) is supported.
-    - Supports 4K VCs for the server board (with 512K control memory) and 1K
-      VCs for the client board (with 128K control memory).
-    - UBR, ABR and CBR service categories are supported.
-    - Only AAL5 is supported.
-    - Supports setting of PCR on the VCs.
-    - Multiple adapters in a system are supported.
-    - All variants of Interphase ATM PCI (i)Chip adapter cards are supported,
-      including x575 (OC3, control memory 128K , 512K and packet memory 128K,
-      512K and 1M), x525 (UTP25) and x531 (DS3 and E3). See
-      http://www.iphase.com/
-      for details.
-    - Only x86 platforms are supported.
-    - SMP is supported.
-
-
-Before You Start
-================
-
-
-Installation
-------------
-
-1. Installing the adapters in the system
-
-   To install the ATM adapters in the system, follow the steps below.
-
-       a. Login as root.
-       b. Shut down the system and power off the system.
-       c. Install one or more ATM adapters in the system.
-       d. Connect each adapter to a port on an ATM switch. The green 'Link'
-	  LED on the front panel of the adapter will be on if the adapter is
-	  connected to the switch properly when the system is powered up.
-       e. Power on and boot the system.
-
-2. [ Removed ]
-
-3. Rebuild kernel with ABR support
-
-   [ a. and b. removed ]
-
-    c. Reconfigure the kernel, choose the Interphase ia driver through "make
-       menuconfig" or "make xconfig".
-    d. Rebuild the kernel, loadable modules and the atm tools.
-    e. Install the new built kernel and modules and reboot.
-
-4. Load the adapter hardware driver (ia driver) if it is built as a module
-
-       a. Login as root.
-       b. Change directory to /lib/modules/<kernel-version>/atm.
-       c. Run "insmod suni.o;insmod iphase.o"
-	  The yellow 'status' LED on the front panel of the adapter will blink
-	  while the driver is loaded in the system.
-       d. To verify that the 'ia' driver is loaded successfully, run the
-	  following command::
-
-	      cat /proc/atm/devices
-
-	  If the driver is loaded successfully, the output of the command will
-	  be similar to the following lines::
-
-	      Itf Type    ESI/"MAC"addr AAL(TX,err,RX,err,drop) ...
-	      0   ia      xxxxxxxxx  0 ( 0 0 0 0 0 )  5 ( 0 0 0 0 0 )
-
-	  You can also check the system log file /var/log/messages for messages
-	  related to the ATM driver.
-
-5. Ia Driver Configuration
-
-5.1 Configuration of adapter buffers
-    The (i)Chip boards have 3 different packet RAM size variants: 128K, 512K and
-    1M. The RAM size decides the number of buffers and buffer size. The default
-    size and number of buffers are set as following:
-
-	=========  =======  ======   ======   ======   ======   ======
-	 Total     Rx RAM   Tx RAM   Rx Buf   Tx Buf   Rx buf   Tx buf
-	 RAM size  size     size     size     size     cnt      cnt
-	=========  =======  ======   ======   ======   ======   ======
-	   128K      64K      64K      10K      10K       6        6
-	   512K     256K     256K      10K      10K      25       25
-	     1M     512K     512K      10K      10K      51       51
-	=========  =======  ======   ======   ======   ======   ======
-
-       These setting should work well in most environments, but can be
-       changed by typing the following command::
-
-	   insmod <IA_DIR>/ia.o IA_RX_BUF=<RX_CNT> IA_RX_BUF_SZ=<RX_SIZE> \
-		   IA_TX_BUF=<TX_CNT> IA_TX_BUF_SZ=<TX_SIZE>
-
-       Where:
-
-	    - RX_CNT = number of receive buffers in the range (1-128)
-	    - RX_SIZE = size of receive buffers in the range (48-64K)
-	    - TX_CNT = number of transmit buffers in the range (1-128)
-	    - TX_SIZE = size of transmit buffers in the range (48-64K)
-
-	    1. Transmit and receive buffer size must be a multiple of 4.
-	    2. Care should be taken so that the memory required for the
-	       transmit and receive buffers is less than or equal to the
-	       total adapter packet memory.
-
-5.2 Turn on ia debug trace
-
-    When the ia driver is built with the CONFIG_ATM_IA_DEBUG flag, the driver
-    can provide more debug trace if needed. There is a bit mask variable,
-    IADebugFlag, which controls the output of the traces. You can find the bit
-    map of the IADebugFlag in iphase.h.
-    The debug trace can be turn on through the insmod command line option, for
-    example, "insmod iphase.o IADebugFlag=0xffffffff" can turn on all the debug
-    traces together with loading the driver.
-
-6. Ia Driver Test Using ttcp_atm and PVC
-
-   For the PVC setup, the test machines can either be connected back-to-back or
-   through a switch. If connected through the switch, the switch must be
-   configured for the PVC(s).
-
-   a. For UBR test:
-
-      At the test machine intended to receive data, type::
-
-	 ttcp_atm -r -a -s 0.100
-
-      At the other test machine, type::
-
-	 ttcp_atm -t -a -s 0.100 -n 10000
-
-      Run "ttcp_atm -h" to display more options of the ttcp_atm tool.
-   b. For ABR test:
-
-      It is the same as the UBR testing, but with an extra command option::
-
-	 -Pabr:max_pcr=<xxx>
-
-      where:
-
-	     xxx = the maximum peak cell rate, from 170 - 353207.
-
-      This option must be set on both the machines.
-
-   c. For CBR test:
-
-      It is the same as the UBR testing, but with an extra command option::
-
-	 -Pcbr:max_pcr=<xxx>
-
-      where:
-
-	     xxx = the maximum peak cell rate, from 170 - 353207.
-
-      This option may only be set on the transmit machine.
-
-
-Outstanding Issues
-==================
-
-
-
-Contact Information
--------------------
-
-::
-
-     Customer Support:
-	 United States:	Telephone:	(214) 654-5555
-			Fax:		(214) 654-5500
-			E-Mail:		intouch@iphase.com
-	 Europe:	Telephone:	33 (0)1 41 15 44 00
-			Fax:		33 (0)1 41 15 12 13
-     World Wide Web:	http://www.iphase.com
-     Anonymous FTP:	ftp.iphase.com
diff --git a/Documentation/networking/device_drivers/ethernet/3com/3c509.rst b/Documentation/networking/device_drivers/ethernet/3com/3c509.rst
deleted file mode 100644
index 47f706b..0000000
--- a/Documentation/networking/device_drivers/ethernet/3com/3c509.rst
+++ /dev/null
@@ -1,249 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-=============================================================================
-Linux and the 3Com EtherLink III Series Ethercards (driver v1.18c and higher)
-=============================================================================
-
-This file contains the instructions and caveats for v1.18c and higher versions
-of the 3c509 driver. You should not use the driver without reading this file.
-
-release 1.0
-
-28 February 2002
-
-Current maintainer (corrections to):
-  David Ruggiero <jdr@farfalle.com>
-
-Introduction
-============
-
-The following are notes and information on using the 3Com EtherLink III series
-ethercards in Linux. These cards are commonly known by the most widely-used
-card's 3Com model number, 3c509. They are all 10mb/s ISA-bus cards and shouldn't
-be (but sometimes are) confused with the similarly-numbered PCI-bus "3c905"
-(aka "Vortex" or "Boomerang") series.  Kernel support for the 3c509 family is
-provided by the module 3c509.c, which has code to support all of the following
-models:
-
- - 3c509 (original ISA card)
- - 3c509B (later revision of the ISA card; supports full-duplex)
- - 3c589 (PCMCIA)
- - 3c589B (later revision of the 3c589; supports full-duplex)
- - 3c579 (EISA)
-
-Large portions of this documentation were heavily borrowed from the guide
-written the original author of the 3c509 driver, Donald Becker. The master
-copy of that document, which contains notes on older versions of the driver,
-currently resides on Scyld web server: http://www.scyld.com/.
-
-
-Special Driver Features
-=======================
-
-Overriding card settings
-
-The driver allows boot- or load-time overriding of the card's detected IOADDR,
-IRQ, and transceiver settings, although this capability shouldn't generally be
-needed except to enable full-duplex mode (see below). An example of the syntax
-for LILO parameters for doing this::
-
-    ether=10,0x310,3,0x3c509,eth0
-
-This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
-transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
-with other card types when overriding the I/O address. When the driver is
-loaded as a module, only the IRQ may be overridden. For example,
-setting two cards to IRQ10 and IRQ11 is done by using the irq module
-option::
-
-   options 3c509 irq=10,11
-
-
-Full-duplex mode
-================
-
-The v1.18c driver added support for the 3c509B's full-duplex capabilities.
-In order to enable and successfully use full-duplex mode, three conditions
-must be met:
-
-(a) You must have a Etherlink III card model whose hardware supports full-
-duplex operations. Currently, the only members of the 3c509 family that are
-positively known to support full-duplex are the 3c509B (ISA bus) and 3c589B
-(PCMCIA) cards. Cards without the "B" model designation do *not* support
-full-duplex mode; these include the original 3c509 (no "B"), the original
-3c589, the 3c529 (MCA bus), and the 3c579 (EISA bus).
-
-(b) You must be using your card's 10baseT transceiver (i.e., the RJ-45
-connector), not its AUI (thick-net) or 10base2 (thin-net/coax) interfaces.
-AUI and 10base2 network cabling is physically incapable of full-duplex
-operation.
-
-(c) Most importantly, your 3c509B must be connected to a link partner that is
-itself full-duplex capable. This is almost certainly one of two things: a full-
-duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
-another system that's connected directly to the 3c509B via a crossover cable.
-
-Full-duplex mode can be enabled using 'ethtool'.
-
-.. warning::
-
-  Extremely important caution concerning full-duplex mode
-
-  Understand that the 3c509B's hardware's full-duplex support is much more
-  limited than that provide by more modern network interface cards. Although
-  at the physical layer of the network it fully supports full-duplex operation,
-  the card was designed before the current Ethernet auto-negotiation (N-way)
-  spec was written. This means that the 3c509B family ***cannot and will not
-  auto-negotiate a full-duplex connection with its link partner under any
-  circumstances, no matter how it is initialized***. If the full-duplex mode
-  of the 3c509B is enabled, its link partner will very likely need to be
-  independently _forced_ into full-duplex mode as well; otherwise various nasty
-  failures will occur - at the very least, you'll see massive numbers of packet
-  collisions. This is one of very rare circumstances where disabling auto-
-  negotiation and forcing the duplex mode of a network interface card or switch
-  would ever be necessary or desirable.
-
-
-Available Transceiver Types
-===========================
-
-For versions of the driver v1.18c and above, the available transceiver types are:
-
-== =========================================================================
-0  transceiver type from EEPROM config (normally 10baseT); force half-duplex
-1  AUI (thick-net / DB15 connector)
-2  (undefined)
-3  10base2 (thin-net == coax / BNC connector)
-4  10baseT (RJ-45 connector); force half-duplex mode
-8  transceiver type and duplex mode taken from card's EEPROM config settings
-12 10baseT (RJ-45 connector); force full-duplex mode
-== =========================================================================
-
-Prior to driver version 1.18c, only transceiver codes 0-4 were supported. Note
-that the new transceiver codes 8 and 12 are the *only* ones that will enable
-full-duplex mode, no matter what the card's detected EEPROM settings might be.
-This insured that merely upgrading the driver from an earlier version would
-never automatically enable full-duplex mode in an existing installation;
-it must always be explicitly enabled via one of these code in order to be
-activated.
-
-The transceiver type can be changed using 'ethtool'.
-
-
-Interpretation of error messages and common problems
-----------------------------------------------------
-
-Error Messages
-^^^^^^^^^^^^^^
-
-eth0: Infinite loop in interrupt, status 2011.
-These are "mostly harmless" message indicating that the driver had too much
-work during that interrupt cycle. With a status of 0x2011 you are receiving
-packets faster than they can be removed from the card. This should be rare
-or impossible in normal operation. Possible causes of this error report are:
-
-   - a "green" mode enabled that slows the processor down when there is no
-     keyboard activity.
-
-   - some other device or device driver hogging the bus or disabling interrupts.
-     Check /proc/interrupts for excessive interrupt counts. The timer tick
-     interrupt should always be incrementing faster than the others.
-
-No received packets
-^^^^^^^^^^^^^^^^^^^
-
-If a 3c509, 3c562 or 3c589 can successfully transmit packets, but never
-receives packets (as reported by /proc/net/dev or 'ifconfig') you likely
-have an interrupt line problem. Check /proc/interrupts to verify that the
-card is actually generating interrupts. If the interrupt count is not
-increasing you likely have a physical conflict with two devices trying to
-use the same ISA IRQ line. The common conflict is with a sound card on IRQ10
-or IRQ5, and the easiest solution is to move the 3c509 to a different
-interrupt line. If the device is receiving packets but 'ping' doesn't work,
-you have a routing problem.
-
-Tx Carrier Errors Reported in /proc/net/dev
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-
-If an EtherLink III appears to transmit packets, but the "Tx carrier errors"
-field in /proc/net/dev increments as quickly as the Tx packet count, you
-likely have an unterminated network or the incorrect media transceiver selected.
-
-3c509B card is not detected on machines with an ISA PnP BIOS.
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-While the updated driver works with most PnP BIOS programs, it does not work
-with all. This can be fixed by disabling PnP support using the 3Com-supplied
-setup program.
-
-3c509 card is not detected on overclocked machines
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Increase the delay time in id_read_eeprom() from the current value, 500,
-to an absurdly high value, such as 5000.
-
-
-Decoding Status and Error Messages
-----------------------------------
-
-
-The bits in the main status register are:
-
-=====	======================================
-value 	description
-=====	======================================
-0x01 	Interrupt latch
-0x02 	Tx overrun, or Rx underrun
-0x04 	Tx complete
-0x08 	Tx FIFO room available
-0x10 	A complete Rx packet has arrived
-0x20 	A Rx packet has started to arrive
-0x40 	The driver has requested an interrupt
-0x80 	Statistics counter nearly full
-=====	======================================
-
-The bits in the transmit (Tx) status word are:
-
-=====	============================================
-value	description
-=====	============================================
-0x02	Out-of-window collision.
-0x04	Status stack overflow (normally impossible).
-0x08	16 collisions.
-0x10	Tx underrun (not enough PCI bus bandwidth).
-0x20	Tx jabber.
-0x40	Tx interrupt requested.
-0x80	Status is valid (this should always be set).
-=====	============================================
-
-
-When a transmit error occurs the driver produces a status message such as::
-
-   eth0: Transmit error, Tx status register 82
-
-The two values typically seen here are:
-
-0x82
-^^^^
-
-Out of window collision. This typically occurs when some other Ethernet
-host is incorrectly set to full duplex on a half duplex network.
-
-0x88
-^^^^
-
-16 collisions. This typically occurs when the network is exceptionally busy
-or when another host doesn't correctly back off after a collision. If this
-error is mixed with 0x82 errors it is the result of a host incorrectly set
-to full duplex (see above).
-
-Both of these errors are the result of network problems that should be
-corrected. They do not represent driver malfunction.
-
-
-Revision history (this file)
-============================
-
-28Feb02 v1.0  DR   New; major portions based on Becker original 3c509 docs
-
diff --git a/Documentation/networking/device_drivers/ethernet/index.rst b/Documentation/networking/device_drivers/ethernet/index.rst
index 5f3f0611..64621c2 100644
--- a/Documentation/networking/device_drivers/ethernet/index.rst
+++ b/Documentation/networking/device_drivers/ethernet/index.rst
@@ -10,7 +10,6 @@
 .. toctree::
    :maxdepth: 2
 
-   3com/3c509
    3com/vortex
    amazon/ena
    altera/altera_tse
@@ -52,7 +51,6 @@
    pensando/ionic
    pensando/ionic_rdma
    qualcomm/ppe/ppe
-   smsc/smc9
    stmicro/stmmac
    ti/cpsw
    ti/cpsw_switchdev
diff --git a/Documentation/networking/device_drivers/ethernet/smsc/smc9.rst b/Documentation/networking/device_drivers/ethernet/smsc/smc9.rst
deleted file mode 100644
index e5eac89..0000000
--- a/Documentation/networking/device_drivers/ethernet/smsc/smc9.rst
+++ /dev/null
@@ -1,48 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-================
-SMC 9xxxx Driver
-================
-
-Revision 0.12
-
-3/5/96
-
-Copyright 1996  Erik Stahlman
-
-Released under terms of the GNU General Public License.
-
-This file contains the instructions and caveats for my SMC9xxx driver.  You
-should not be using the driver without reading this file.
-
-Things to note about installation:
-
-  1. The driver should work on all kernels from 1.2.13 until 1.3.71.
-     (A kernel patch is supplied for 1.3.71 )
-
-  2. If you include this into the kernel, you might need to change some
-     options, such as for forcing IRQ.
-
-
-  3.  To compile as a module, run 'make'.
-      Make will give you the appropriate options for various kernel support.
-
-  4.  Loading the driver as a module::
-
-	use:   insmod smc9194.o
-	optional parameters:
-		io=xxxx    : your base address
-		irq=xx	   : your irq
-		ifport=x   :	0 for whatever is default
-				1 for twisted pair
-				2 for AUI  ( or BNC on some cards )
-
-How to obtain the latest version?
-
-FTP:
-	ftp://fenris.campus.vt.edu/smc9/smc9-12.tar.gz
-	ftp://sfbox.vt.edu/filebox/F/fenris/smc9/smc9-12.tar.gz
-
-
-Contacting me:
-    erik@mail.vt.edu
diff --git a/Documentation/networking/device_drivers/hamradio/baycom.rst b/Documentation/networking/device_drivers/hamradio/baycom.rst
deleted file mode 100644
index fe2d010..0000000
--- a/Documentation/networking/device_drivers/hamradio/baycom.rst
+++ /dev/null
@@ -1,174 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-
-===============================
-Linux Drivers for Baycom Modems
-===============================
-
-Thomas M. Sailer, HB9JNX/AE4WA, <sailer@ife.ee.ethz.ch>
-
-The drivers for the baycom modems have been split into
-separate drivers as they did not share any code, and the driver
-and device names have changed.
-
-This document describes the Linux Kernel Drivers for simple Baycom style
-amateur radio modems.
-
-The following drivers are available:
-====================================
-
-baycom_ser_fdx:
-  This driver supports the SER12 modems either full or half duplex.
-  Its baud rate may be changed via the ``baud`` module parameter,
-  therefore it supports just about every bit bang modem on a
-  serial port. Its devices are called bcsf0 through bcsf3.
-  This is the recommended driver for SER12 type modems,
-  however if you have a broken UART clone that does not have working
-  delta status bits, you may try baycom_ser_hdx.
-
-baycom_ser_hdx:
-  This is an alternative driver for SER12 type modems.
-  It only supports half duplex, and only 1200 baud. Its devices
-  are called bcsh0 through bcsh3. Use this driver only if baycom_ser_fdx
-  does not work with your UART.
-
-baycom_par:
-  This driver supports the par96 and picpar modems.
-  Its devices are called bcp0 through bcp3.
-
-baycom_epp:
-  This driver supports the EPP modem.
-  Its devices are called bce0 through bce3.
-  This driver is work-in-progress.
-
-The following modems are supported:
-
-======= ========================================================================
-ser12   This is a very simple 1200 baud AFSK modem. The modem consists only
-	of a modulator/demodulator chip, usually a TI TCM3105. The computer
-	is responsible for regenerating the receiver bit clock, as well as
-	for handling the HDLC protocol. The modem connects to a serial port,
-	hence the name. Since the serial port is not used as an async serial
-	port, the kernel driver for serial ports cannot be used, and this
-	driver only supports standard serial hardware (8250, 16450, 16550)
-
-par96   This is a modem for 9600 baud FSK compatible to the G3RUH standard.
-	The modem does all the filtering and regenerates the receiver clock.
-	Data is transferred from and to the PC via a shift register.
-	The shift register is filled with 16 bits and an interrupt is signalled.
-	The PC then empties the shift register in a burst. This modem connects
-	to the parallel port, hence the name. The modem leaves the
-	implementation of the HDLC protocol and the scrambler polynomial to
-	the PC.
-
-picpar  This is a redesign of the par96 modem by Henning Rech, DF9IC. The modem
-	is protocol compatible to par96, but uses only three low power ICs
-	and can therefore be fed from the parallel port and does not require
-	an additional power supply. Furthermore, it incorporates a carrier
-	detect circuitry.
-
-EPP     This is a high-speed modem adaptor that connects to an enhanced parallel
-	port.
-
-	Its target audience is users working over a high speed hub (76.8kbit/s).
-
-eppfpga This is a redesign of the EPP adaptor.
-======= ========================================================================
-
-All of the above modems only support half duplex communications. However,
-the driver supports the KISS (see below) fullduplex command. It then simply
-starts to send as soon as there's a packet to transmit and does not care
-about DCD, i.e. it starts to send even if there's someone else on the channel.
-This command is required by some implementations of the DAMA channel
-access protocol.
-
-
-The Interface of the drivers
-============================
-
-Unlike previous drivers, these drivers are no longer character devices,
-but they are now true kernel network interfaces. Installation is therefore
-simple. Once installed, four interfaces named bc{sf,sh,p,e}[0-3] are available.
-sethdlc from the ax25 utilities may be used to set driver states etc.
-Users of userland AX.25 stacks may use the net2kiss utility (also available
-in the ax25 utilities package) to convert packets of a network interface
-to a KISS stream on a pseudo tty. There's also a patch available from
-me for WAMPES which allows attaching a kernel network interface directly.
-
-
-Configuring the driver
-======================
-
-Every time a driver is inserted into the kernel, it has to know which
-modems it should access at which ports. This can be done with the setbaycom
-utility. If you are only using one modem, you can also configure the
-driver from the insmod command line (or by means of an option line in
-``/etc/modprobe.d/*.conf``).
-
-Examples::
-
-  modprobe baycom_ser_fdx mode="ser12*" iobase=0x3f8 irq=4
-  sethdlc -i bcsf0 -p mode "ser12*" io 0x3f8 irq 4
-
-Both lines configure the first port to drive a ser12 modem at the first
-serial port (COM1 under DOS). The * in the mode parameter instructs the driver
-to use the software DCD algorithm (see below)::
-
-  insmod baycom_par mode="picpar" iobase=0x378
-  sethdlc -i bcp0 -p mode "picpar" io 0x378
-
-Both lines configure the first port to drive a picpar modem at the
-first parallel port (LPT1 under DOS). (Note: picpar implies
-hardware DCD, par96 implies software DCD).
-
-The channel access parameters can be set with sethdlc -a or kissparms.
-Note that both utilities interpret the values slightly differently.
-
-
-Hardware DCD versus Software DCD
-================================
-
-To avoid collisions on the air, the driver must know when the channel is
-busy. This is the task of the DCD circuitry/software. The driver may either
-utilise a software DCD algorithm (options=1) or use a DCD signal from
-the hardware (options=0).
-
-======= =================================================================
-ser12   if software DCD is utilised, the radio's squelch should always be
-	open. It is highly recommended to use the software DCD algorithm,
-	as it is much faster than most hardware squelch circuitry. The
-	disadvantage is a slightly higher load on the system.
-
-par96   the software DCD algorithm for this type of modem is rather poor.
-	The modem simply does not provide enough information to implement
-	a reasonable DCD algorithm in software. Therefore, if your radio
-	feeds the DCD input of the PAR96 modem, the use of the hardware
-	DCD circuitry is recommended.
-
-picpar  the picpar modem features a builtin DCD hardware, which is highly
-	recommended.
-======= =================================================================
-
-
-
-Compatibility with the rest of the Linux kernel
-===============================================
-
-The serial driver and the baycom serial drivers compete
-for the same hardware resources. Of course only one driver can access a given
-interface at a time. The serial driver grabs all interfaces it can find at
-startup time. Therefore the baycom drivers subsequently won't be able to
-access a serial port. You might therefore find it necessary to release
-a port owned by the serial driver with 'setserial /dev/ttyS# uart none', where
-# is the number of the interface. The baycom drivers do not reserve any
-ports at startup, unless one is specified on the 'insmod' command line. Another
-method to solve the problem is to compile all drivers as modules and
-leave it to kmod to load the correct driver depending on the application.
-
-The parallel port drivers (baycom_par, baycom_epp) now use the parport subsystem
-to arbitrate the ports between different client drivers.
-
-vy 73s de
-
-Tom Sailer, sailer@ife.ee.ethz.ch
-
-hb9jnx @ hb9w.ampr.org
diff --git a/Documentation/networking/device_drivers/hamradio/index.rst b/Documentation/networking/device_drivers/hamradio/index.rst
deleted file mode 100644
index 6af481c..0000000
--- a/Documentation/networking/device_drivers/hamradio/index.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
-
-Amateur Radio Device Drivers
-============================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   baycom
-   z8530drv
diff --git a/Documentation/networking/device_drivers/hamradio/z8530drv.rst b/Documentation/networking/device_drivers/hamradio/z8530drv.rst
deleted file mode 100644
index d294276..0000000
--- a/Documentation/networking/device_drivers/hamradio/z8530drv.rst
+++ /dev/null
@@ -1,686 +0,0 @@
-.. SPDX-License-Identifier: GPL-2.0
-.. include:: <isonum.txt>
-
-=========================================================
-SCC.C - Linux driver for Z8530 based HDLC cards for AX.25
-=========================================================
-
-
-This is a subset of the documentation. To use this driver you MUST have the
-full package from:
-
-Internet:
-
-    1. ftp://ftp.ccac.rwth-aachen.de/pub/jr/z8530drv-utils_3.0-3.tar.gz
-
-    2. ftp://ftp.pspt.fi/pub/ham/linux/ax25/z8530drv-utils_3.0-3.tar.gz
-
-Please note that the information in this document may be hopelessly outdated.
-A new version of the documentation, along with links to other important
-Linux Kernel AX.25 documentation and programs, is available on
-http://yaina.de/jreuter
-
-Copyright |copy| 1993,2000 by Joerg Reuter DL1BKE <jreuter@yaina.de>
-
-portions Copyright |copy| 1993 Guido ten Dolle PE1NNZ
-
-for the complete copyright notice see >> Copying.Z8530DRV <<
-
-1. Initialization of the driver
-===============================
-
-To use the driver, 3 steps must be performed:
-
-     1. if compiled as module: loading the module
-     2. Setup of hardware, MODEM and KISS parameters with sccinit
-     3. Attach each channel to the Linux kernel AX.25 with "ifconfig"
-
-Unlike the versions below 2.4 this driver is a real network device
-driver. If you want to run xNOS instead of our fine kernel AX.25
-use a 2.x version (available from above sites) or read the
-AX.25-HOWTO on how to emulate a KISS TNC on network device drivers.
-
-
-1.1 Loading the module
-======================
-
-(If you're going to compile the driver as a part of the kernel image,
- skip this chapter and continue with 1.2)
-
-Before you can use a module, you'll have to load it with::
-
-	insmod scc.o
-
-please read 'man insmod' that comes with module-init-tools.
-
-You should include the insmod in one of the /etc/rc.d/rc.* files,
-and don't forget to insert a call of sccinit after that. It
-will read your /etc/z8530drv.conf.
-
-1.2. /etc/z8530drv.conf
-=======================
-
-To setup all parameters you must run /sbin/sccinit from one
-of your rc.*-files. This has to be done BEFORE you can
-"ifconfig" an interface. Sccinit reads the file /etc/z8530drv.conf
-and sets the hardware, MODEM and KISS parameters. A sample file is
-delivered with this package. Change it to your needs.
-
-The file itself consists of two main sections.
-
-1.2.1 configuration of hardware parameters
-==========================================
-
-The hardware setup section defines the following parameters for each
-Z8530::
-
-    chip    1
-    data_a  0x300                   # data port A
-    ctrl_a  0x304                   # control port A
-    data_b  0x301                   # data port B
-    ctrl_b  0x305                   # control port B
-    irq     5                       # IRQ No. 5
-    pclock  4915200                 # clock
-    board   BAYCOM                  # hardware type
-    escc    no                      # enhanced SCC chip? (8580/85180/85280)
-    vector  0                       # latch for interrupt vector
-    special no                      # address of special function register
-    option  0                       # option to set via sfr
-
-
-chip
-	- this is just a delimiter to make sccinit a bit simpler to
-	  program. A parameter has no effect.
-
-data_a
-	- the address of the data port A of this Z8530 (needed)
-ctrl_a
-	- the address of the control port A (needed)
-data_b
-	- the address of the data port B (needed)
-ctrl_b
-	- the address of the control port B (needed)
-
-irq
-	- the used IRQ for this chip. Different chips can use different
-	  IRQs or the same. If they share an interrupt, it needs to be
-	  specified within one chip-definition only.
-
-pclock  - the clock at the PCLK pin of the Z8530 (option, 4915200 is
-	  default), measured in Hertz
-
-board
-	- the "type" of the board:
-
-	   =======================  ========
-	   SCC type                 value
-	   =======================  ========
-	   PA0HZP SCC card          PA0HZP
-	   EAGLE card               EAGLE
-	   PC100 card               PC100
-	   PRIMUS-PC (DG9BL) card   PRIMUS
-	   BayCom (U)SCC card       BAYCOM
-	   =======================  ========
-
-escc
-	- if you want support for ESCC chips (8580, 85180, 85280), set
-	  this to "yes" (option, defaults to "no")
-
-vector
-	- address of the vector latch (aka "intack port") for PA0HZP
-	  cards. There can be only one vector latch for all chips!
-	  (option, defaults to 0)
-
-special
-	- address of the special function register on several cards.
-	  (option, defaults to 0)
-
-option  - The value you write into that register (option, default is 0)
-
-You can specify up to four chips (8 channels). If this is not enough,
-just change::
-
-	#define MAXSCC 4
-
-to a higher value.
-
-Example for the BAYCOM USCC:
-----------------------------
-
-::
-
-	chip    1
-	data_a  0x300                   # data port A
-	ctrl_a  0x304                   # control port A
-	data_b  0x301                   # data port B
-	ctrl_b  0x305                   # control port B
-	irq     5                       # IRQ No. 5 (#)
-	board   BAYCOM                  # hardware type (*)
-	#
-	# SCC chip 2
-	#
-	chip    2
-	data_a  0x302
-	ctrl_a  0x306
-	data_b  0x303
-	ctrl_b  0x307
-	board   BAYCOM
-
-An example for a PA0HZP card:
------------------------------
-
-::
-
-	chip 1
-	data_a 0x153
-	data_b 0x151
-	ctrl_a 0x152
-	ctrl_b 0x150
-	irq 9
-	pclock 4915200
-	board PA0HZP
-	vector 0x168
-	escc no
-	#
-	#
-	#
-	chip 2
-	data_a 0x157
-	data_b 0x155
-	ctrl_a 0x156
-	ctrl_b 0x154
-	irq 9
-	pclock 4915200
-	board PA0HZP
-	vector 0x168
-	escc no
-
-A DRSI would should probably work with this:
---------------------------------------------
-(actually: two DRSI cards...)
-
-::
-
-	chip 1
-	data_a 0x303
-	data_b 0x301
-	ctrl_a 0x302
-	ctrl_b 0x300
-	irq 7
-	pclock 4915200
-	board DRSI
-	escc no
-	#
-	#
-	#
-	chip 2
-	data_a 0x313
-	data_b 0x311
-	ctrl_a 0x312
-	ctrl_b 0x310
-	irq 7
-	pclock 4915200
-	board DRSI
-	escc no
-
-Note that you cannot use the on-board baudrate generator off DRSI
-cards. Use "mode dpll" for clock source (see below).
-
-This is based on information provided by Mike Bilow (and verified
-by Paul Helay)
-
-The utility "gencfg"
---------------------
-
-If you only know the parameters for the PE1CHL driver for DOS,
-run gencfg. It will generate the correct port addresses (I hope).
-Its parameters are exactly the same as the ones you use with
-the "attach scc" command in net, except that the string "init" must
-not appear. Example::
-
-	gencfg 2 0x150 4 2 0 1 0x168 9 4915200
-
-will print a skeleton z8530drv.conf for the OptoSCC to stdout.
-
-::
-
-	gencfg 2 0x300 2 4 5 -4 0 7 4915200 0x10
-
-does the same for the BAYCOM USCC card. In my opinion it is much easier
-to edit scc_config.h...
-
-
-1.2.2 channel configuration
-===========================
-
-The channel definition is divided into three sub sections for each
-channel:
-
-An example for scc0::
-
-	# DEVICE
-
-	device scc0	# the device for the following params
-
-	# MODEM / BUFFERS
-
-	speed 1200		# the default baudrate
-	clock dpll		# clock source:
-				# 	dpll     = normal half duplex operation
-				# 	external = MODEM provides own Rx/Tx clock
-				#	divider  = use full duplex divider if
-				#		   installed (1)
-	mode nrzi		# HDLC encoding mode
-				#	nrzi = 1k2 MODEM, G3RUH 9k6 MODEM
-				#	nrz  = DF9IC 9k6 MODEM
-				#
-	bufsize	384		# size of buffers. Note that this must include
-				# the AX.25 header, not only the data field!
-				# (optional, defaults to 384)
-
-	# KISS (Layer 1)
-
-	txdelay 36              # (see chapter 1.4)
-	persist 64
-	slot    8
-	tail    8
-	fulldup 0
-	wait    12
-	min     3
-	maxkey  7
-	idle    3
-	maxdef  120
-	group   0
-	txoff   off
-	softdcd on
-	slip    off
-
-The order WITHIN these sections is unimportant. The order OF these
-sections IS important. The MODEM parameters are set with the first
-recognized KISS parameter...
-
-Please note that you can initialize the board only once after boot
-(or insmod). You can change all parameters but "mode" and "clock"
-later with the Sccparam program or through KISS. Just to avoid
-security holes...
-
-(1) this divider is usually mounted on the SCC-PBC (PA0HZP) or not
-    present at all (BayCom). It feeds back the output of the DPLL
-    (digital pll) as transmit clock. Using this mode without a divider
-    installed will normally result in keying the transceiver until
-    maxkey expires --- of course without sending anything (useful).
-
-2. Attachment of a channel by your AX.25 software
-=================================================
-
-2.1 Kernel AX.25
-================
-
-To set up an AX.25 device you can simply type::
-
-	ifconfig scc0 44.128.1.1 hw ax25 dl0tha-7
-
-This will create a network interface with the IP number 44.128.20.107
-and the callsign "dl0tha". If you do not have any IP number (yet) you
-can use any of the 44.128.0.0 network. Note that you do not need
-axattach. The purpose of axattach (like slattach) is to create a KISS
-network device linked to a TTY. Please read the documentation of the
-ax25-utils and the AX.25-HOWTO to learn how to set the parameters of
-the kernel AX.25.
-
-2.2 NOS, NET and TFKISS
-=======================
-
-Since the TTY driver (aka KISS TNC emulation) is gone you need
-to emulate the old behaviour. The cost of using these programs is
-that you probably need to compile the kernel AX.25, regardless of whether
-you actually use it or not. First setup your /etc/ax25/axports,
-for example::
-
-	9k6	dl0tha-9  9600  255 4 9600 baud port (scc3)
-	axlink	dl0tha-15 38400 255 4 Link to NOS
-
-Now "ifconfig" the scc device::
-
-	ifconfig scc3 44.128.1.1 hw ax25 dl0tha-9
-
-You can now axattach a pseudo-TTY::
-
-	axattach /dev/ptys0 axlink
-
-and start your NOS and attach /dev/ptys0 there. The problem is that
-NOS is reachable only via digipeating through the kernel AX.25
-(disastrous on a DAMA controlled channel). To solve this problem,
-configure "rxecho" to echo the incoming frames from "9k6" to "axlink"
-and outgoing frames from "axlink" to "9k6" and start::
-
-	rxecho
-
-Or simply use "kissbridge" coming with z8530drv-utils::
-
-	ifconfig scc3 hw ax25 dl0tha-9
-	kissbridge scc3 /dev/ptys0
-
-
-3. Adjustment and Display of parameters
-=======================================
-
-3.1 Displaying SCC Parameters:
-==============================
-
-Once a SCC channel has been attached, the parameter settings and
-some statistic information can be shown using the param program::
-
-	dl1bke-u:~$ sccstat scc0
-
-	Parameters:
-
-	speed       : 1200 baud
-	txdelay     : 36
-	persist     : 255
-	slottime    : 0
-	txtail      : 8
-	fulldup     : 1
-	waittime    : 12
-	mintime     : 3 sec
-	maxkeyup    : 7 sec
-	idletime    : 3 sec
-	maxdefer    : 120 sec
-	group       : 0x00
-	txoff       : off
-	softdcd     : on
-	SLIP        : off
-
-	Status:
-
-	HDLC                  Z8530           Interrupts         Buffers
-	-----------------------------------------------------------------------
-	Sent       :     273  RxOver :     0  RxInts :   125074  Size    :  384
-	Received   :    1095  TxUnder:     0  TxInts :     4684  NoSpace :    0
-	RxErrors   :    1591                  ExInts :    11776
-	TxErrors   :       0                  SpInts :     1503
-	Tx State   :    idle
-
-
-The status info shown is:
-
-==============	==============================================================
-Sent		number of frames transmitted
-Received	number of frames received
-RxErrors	number of receive errors (CRC, ABORT)
-TxErrors	number of discarded Tx frames (due to various reasons)
-Tx State	status of the Tx interrupt handler: idle/busy/active/tail (2)
-RxOver		number of receiver overruns
-TxUnder		number of transmitter underruns
-RxInts		number of receiver interrupts
-TxInts		number of transmitter interrupts
-EpInts		number of receiver special condition interrupts
-SpInts		number of external/status interrupts
-Size		maximum size of an AX.25 frame (*with* AX.25 headers!)
-NoSpace		number of times a buffer could not get allocated
-==============	==============================================================
-
-An overrun is abnormal. If lots of these occur, the product of
-baudrate and number of interfaces is too high for the processing
-power of your computer. NoSpace errors are unlikely to be caused by the
-driver or the kernel AX.25.
-
-
-3.2 Setting Parameters
-======================
-
-
-The setting of parameters of the emulated KISS TNC is done in the
-same way in the SCC driver. You can change parameters by using
-the kissparms program from the ax25-utils package or use the program
-"sccparam"::
-
-     sccparam <device> <paramname> <decimal-|hexadecimal value>
-
-You can change the following parameters:
-
-===========   =====
-param	      value
-===========   =====
-speed         1200
-txdelay       36
-persist       255
-slottime      0
-txtail        8
-fulldup       1
-waittime      12
-mintime       3
-maxkeyup      7
-idletime      3
-maxdefer      120
-group         0x00
-txoff         off
-softdcd       on
-SLIP          off
-===========   =====
-
-
-The parameters have the following meaning:
-
-speed:
-     The baudrate on this channel in bits/sec
-
-     Example: sccparam /dev/scc3 speed 9600
-
-txdelay:
-     The delay (in units of 10 ms) after keying of the
-     transmitter, until the first byte is sent. This is usually
-     called "TXDELAY" in a TNC.  When 0 is specified, the driver
-     will just wait until the CTS signal is asserted. This
-     assumes the presence of a timer or other circuitry in the
-     MODEM and/or transmitter, that asserts CTS when the
-     transmitter is ready for data.
-     A normal value of this parameter is 30-36.
-
-     Example: sccparam /dev/scc0 txd 20
-
-persist:
-     This is the probability that the transmitter will be keyed
-     when the channel is found to be free.  It is a value from 0
-     to 255, and the probability is (value+1)/256.  The value
-     should be somewhere near 50-60, and should be lowered when
-     the channel is used more heavily.
-
-     Example: sccparam /dev/scc2 persist 20
-
-slottime:
-     This is the time between samples of the channel. It is
-     expressed in units of 10 ms.  About 200-300 ms (value 20-30)
-     seems to be a good value.
-
-     Example: sccparam /dev/scc0 slot 20
-
-tail:
-     The time the transmitter will remain keyed after the last
-     byte of a packet has been transferred to the SCC. This is
-     necessary because the CRC and a flag still have to leave the
-     SCC before the transmitter is keyed down. The value depends
-     on the baudrate selected.  A few character times should be
-     sufficient, e.g. 40ms at 1200 baud. (value 4)
-     The value of this parameter is in 10 ms units.
-
-     Example: sccparam /dev/scc2 4
-
-full:
-     The full-duplex mode switch. This can be one of the following
-     values:
-
-     0:   The interface will operate in CSMA mode (the normal
-	  half-duplex packet radio operation)
-     1:   Fullduplex mode, i.e. the transmitter will be keyed at
-	  any time, without checking the received carrier.  It
-	  will be unkeyed when there are no packets to be sent.
-     2:   Like 1, but the transmitter will remain keyed, also
-	  when there are no packets to be sent.  Flags will be
-	  sent in that case, until a timeout (parameter 10)
-	  occurs.
-
-     Example: sccparam /dev/scc0 fulldup off
-
-wait:
-     The initial waittime before any transmit attempt, after the
-     frame has been queue for transmit.  This is the length of
-     the first slot in CSMA mode.  In full duplex modes it is
-     set to 0 for maximum performance.
-     The value of this parameter is in 10 ms units.
-
-     Example: sccparam /dev/scc1 wait 4
-
-maxkey:
-     The maximal time the transmitter will be keyed to send
-     packets, in seconds.  This can be useful on busy CSMA
-     channels, to avoid "getting a bad reputation" when you are
-     generating a lot of traffic.  After the specified time has
-     elapsed, no new frame will be started. Instead, the trans-
-     mitter will be switched off for a specified time (parameter
-     min), and then the selected algorithm for keyup will be
-     started again.
-     The value 0 as well as "off" will disable this feature,
-     and allow infinite transmission time.
-
-     Example: sccparam /dev/scc0 maxk 20
-
-min:
-     This is the time the transmitter will be switched off when
-     the maximum transmission time is exceeded.
-
-     Example: sccparam /dev/scc3 min 10
-
-idle:
-     This parameter specifies the maximum idle time in full duplex
-     2 mode, in seconds.  When no frames have been sent for this
-     time, the transmitter will be keyed down.  A value of 0 is
-     has same result as the fullduplex mode 1. This parameter
-     can be disabled.
-
-     Example: sccparam /dev/scc2 idle off	# transmit forever
-
-maxdefer
-     This is the maximum time (in seconds) to wait for a free channel
-     to send. When this timer expires the transmitter will be keyed
-     IMMEDIATELY. If you love to get trouble with other users you
-     should set this to a very low value ;-)
-
-     Example: sccparam /dev/scc0 maxdefer 240	# 2 minutes
-
-
-txoff:
-     When this parameter has the value 0, the transmission of packets
-     is enable. Otherwise it is disabled.
-
-     Example: sccparam /dev/scc2 txoff on
-
-group:
-     It is possible to build special radio equipment to use more than
-     one frequency on the same band, e.g. using several receivers and
-     only one transmitter that can be switched between frequencies.
-     Also, you can connect several radios that are active on the same
-     band.  In these cases, it is not possible, or not a good idea, to
-     transmit on more than one frequency.  The SCC driver provides a
-     method to lock transmitters on different interfaces, using the
-     "param <interface> group <x>" command.  This will only work when
-     you are using CSMA mode (parameter full = 0).
-
-     The number <x> must be 0 if you want no group restrictions, and
-     can be computed as follows to create restricted groups:
-     <x> is the sum of some OCTAL numbers:
-
-
-     ===  =======================================================
-     200  This transmitter will only be keyed when all other
-	  transmitters in the group are off.
-     100  This transmitter will only be keyed when the carrier
-	  detect of all other interfaces in the group is off.
-     0xx  A byte that can be used to define different groups.
-	  Interfaces are in the same group, when the logical AND
-	  between their xx values is nonzero.
-     ===  =======================================================
-
-     Examples:
-
-     When 2 interfaces use group 201, their transmitters will never be
-     keyed at the same time.
-
-     When 2 interfaces use group 101, the transmitters will only key
-     when both channels are clear at the same time.  When group 301,
-     the transmitters will not be keyed at the same time.
-
-     Don't forget to convert the octal numbers into decimal before
-     you set the parameter.
-
-     Example: (to be written)
-
-softdcd:
-     use a software dcd instead of the real one... Useful for a very
-     slow squelch.
-
-     Example: sccparam /dev/scc0 soft on
-
-
-4. Problems
-===========
-
-If you have tx-problems with your BayCom USCC card please check
-the manufacturer of the 8530. SGS chips have a slightly
-different timing. Try Zilog...  A solution is to write to register 8
-instead to the data port, but this won't work with the ESCC chips.
-*SIGH!*
-
-A very common problem is that the PTT locks until the maxkeyup timer
-expires, although interrupts and clock source are correct. In most
-cases compiling the driver with CONFIG_SCC_DELAY (set with
-make config) solves the problems. For more hints read the (pseudo) FAQ
-and the documentation coming with z8530drv-utils.
-
-I got reports that the driver has problems on some 386-based systems.
-(i.e. Amstrad) Those systems have a bogus AT bus timing which will
-lead to delayed answers on interrupts. You can recognize these
-problems by looking at the output of Sccstat for the suspected
-port. If it shows under- and overruns you own such a system.
-
-Delayed processing of received data: This depends on
-
-- the kernel version
-
-- kernel profiling compiled or not
-
-- a high interrupt load
-
-- a high load of the machine --- running X, Xmorph, XV and Povray,
-  while compiling the kernel... hmm ... even with 32 MB RAM ...  ;-)
-  Or running a named for the whole .ampr.org domain on an 8 MB
-  box...
-
-- using information from rxecho or kissbridge.
-
-Kernel panics: please read /linux/README and find out if it
-really occurred within the scc driver.
-
-If you cannot solve a problem, send me
-
-- a description of the problem,
-- information on your hardware (computer system, scc board, modem)
-- your kernel version
-- the output of cat /proc/net/z8530
-
-4. Thor RLC100
-==============
-
-Mysteriously this board seems not to work with the driver. Anyone
-got it up-and-running?
-
-
-Many thanks to Linus Torvalds and Alan Cox for including the driver
-in the Linux standard distribution and their support.
-
-::
-
-	Joerg Reuter	ampr-net: dl1bke@db0pra.ampr.org
-			AX-25   : DL1BKE @ DB0ABH.#BAY.DEU.EU
-			Internet: jreuter@yaina.de
-			WWW     : http://yaina.de/jreuter
diff --git a/Documentation/networking/device_drivers/index.rst b/Documentation/networking/device_drivers/index.rst
index 1df51c9..1f54f01 100644
--- a/Documentation/networking/device_drivers/index.rst
+++ b/Documentation/networking/device_drivers/index.rst
@@ -13,6 +13,5 @@
    cellular/index
    ethernet/index
    fddi/index
-   hamradio/index
    wifi/index
    wwan/index
diff --git a/Documentation/networking/index.rst b/Documentation/networking/index.rst
index c2406bd..44a422a 100644
--- a/Documentation/networking/index.rst
+++ b/Documentation/networking/index.rst
@@ -17,7 +17,6 @@
    diagnostic/index
    dsa/index
    devlink/index
-   caif/index
    ethtool-netlink
    ieee802154
    iso15765-2
@@ -41,11 +40,9 @@
    tls-handshake
    nfc
    6lowpan
-   6pack
    arcnet-hardware
    arcnet
    atm
-   ax25
    bonding
    cdc_mbim
    dctcp
diff --git a/Documentation/networking/netdevices.rst b/Documentation/networking/netdevices.rst
index 83e28b9..93e06e8 100644
--- a/Documentation/networking/netdevices.rst
+++ b/Documentation/networking/netdevices.rst
@@ -289,6 +289,19 @@
 ndo_set_rx_mode:
 	Synchronization: netif_addr_lock spinlock.
 	Context: BHs disabled
+	Notes: Deprecated in favor of ndo_set_rx_mode_async which runs
+	in process context.
+
+ndo_set_rx_mode_async:
+	Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+	lock if the driver implements queue management or shaper API.
+	Context: process (from a work queue)
+	Notes: Async version of ndo_set_rx_mode which runs in process
+	context. Receives snapshots of the unicast and multicast address lists.
+
+ndo_change_rx_flags:
+	Synchronization: rtnl_lock() semaphore. In addition, netdev instance
+	lock if the driver implements queue management or shaper API.
 
 ndo_setup_tc:
 	``TC_SETUP_BLOCK`` and ``TC_SETUP_FT`` are running under NFT locks
diff --git a/Documentation/process/license-rules.rst b/Documentation/process/license-rules.rst
index 59a7832d..b0176bb 100644
--- a/Documentation/process/license-rules.rst
+++ b/Documentation/process/license-rules.rst
@@ -63,8 +63,11 @@
    The SPDX license identifier in kernel files shall be added at the first
    possible line in a file which can contain a comment.  For the majority
    of files this is the first line, except for scripts which require the
-   '#!PATH_TO_INTERPRETER' in the first line.  For those scripts the SPDX
-   identifier goes into the second line.
+   '#!PATH_TO_INTERPRETER' in the first line.  For those scripts, the SPDX
+   license identifier goes into the second line.
+
+   The license identifier line can then be followed by one or multiple
+   SPDX-FileCopyrightText lines if desired.
 
 |
 
diff --git a/Documentation/process/maintainer-netdev.rst b/Documentation/process/maintainer-netdev.rst
index bda93b4..ec7b9aa 100644
--- a/Documentation/process/maintainer-netdev.rst
+++ b/Documentation/process/maintainer-netdev.rst
@@ -528,7 +528,7 @@
    status will be withdrawn.
 
 5. Test failures due to bugs either in the driver or the test itself,
-   or lack of support for the feature the test is targgeting are
+   or lack of support for the feature the test is targeting are
    *not* a basis for losing the ``Supported`` status.
 
 netdev CI will maintain an official page of supported devices, listing their
diff --git a/Documentation/process/maintainer-soc.rst b/Documentation/process/maintainer-soc.rst
index 7d6bad9..a3a90a7 100644
--- a/Documentation/process/maintainer-soc.rst
+++ b/Documentation/process/maintainer-soc.rst
@@ -169,8 +169,6 @@
 For new platforms, or additions to existing ones, ``make dtbs_check`` should not
 add any new warnings.  For RISC-V and Samsung SoC, ``make dtbs_check W=1`` is
 required to not add any new warnings.
-If in any doubt about a devicetree change, reach out to the devicetree
-maintainers.
 
 Branches and Pull Requests
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -209,3 +207,13 @@
 a signed tag, rather than a branch.  This tag should contain a short description
 summarising the changes in the pull request.  For more detail on sending pull
 requests, please see Documentation/maintainer/pull-requests.rst.
+
+Defconfigs purpose
+~~~~~~~~~~~~~~~~~~
+
+Defconfigs are primarily used by the kernel developers, because distros have
+their own configs.  A change adding new CONFIG options to a defconfig should
+explain why the kernel developers in general would want such option, e.g. by
+providing a name of an upstream-supported machine/board using that new option.
+This implies that enabling options in defconfig for non-upstream machines shall
+not be accepted.
diff --git a/Documentation/staging/magic-number.rst b/Documentation/staging/magic-number.rst
index 79afddf..670d318 100644
--- a/Documentation/staging/magic-number.rst
+++ b/Documentation/staging/magic-number.rst
@@ -72,11 +72,8 @@
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip/slip.h``
-BAYCOM_MAGIC          19730510         baycom_state             ``drivers/net/hamradio/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/subsystem-apis.rst b/Documentation/subsystem-apis.rst
index ff4fe8c..b1ad48b 100644
--- a/Documentation/subsystem-apis.rst
+++ b/Documentation/subsystem-apis.rst
@@ -46,7 +46,6 @@
    networking/index
    netlabel/index
    infiniband/index
-   isdn/index
    mhi/index
 
 Storage interfaces
diff --git a/Documentation/sunrpc/xdr/nlm4.x b/Documentation/sunrpc/xdr/nlm4.x
new file mode 100644
index 0000000..0c44a80
--- /dev/null
+++ b/Documentation/sunrpc/xdr/nlm4.x
@@ -0,0 +1,211 @@
+/*
+ * This file was extracted by hand from
+ * https://www.rfc-editor.org/rfc/rfc1813.html .
+ *
+ * Note that RFC 1813 is Informational. Its official date of
+ * publication (June 1995) is before the IETF required its RFCs to
+ * carry an explicit copyright or other IP ownership notices.
+ *
+ * Note also that RFC 1813 does not specify the whole NLM4 protocol.
+ * In particular, the argument and result types are not present in
+ * that document, and had to be reverse-engineered.
+ */
+
+/*
+ * The NLMv4 protocol
+ */
+
+pragma header nlm4;
+
+/*
+ * The following definitions are missing in RFC 1813,
+ * but can be found in the OpenNetworking Network Lock
+ * Manager protocol:
+ *
+ * https://pubs.opengroup.org/onlinepubs/9629799/chap10.htm
+ */
+
+const LM_MAXSTRLEN = 1024;
+
+const LM_MAXNAMELEN = 1025;
+
+const MAXNETOBJ_SZ = 1024;
+
+typedef opaque netobj<MAXNETOBJ_SZ>;
+
+enum fsh4_mode {
+	fsm_DN = 0,		/* deny none */
+	fsm_DR = 1,		/* deny read */
+	fsm_DW = 2,		/* deny write */
+	fsm_DRW = 3		/* deny read/write */
+};
+
+enum fsh4_access {
+	fsa_NONE = 0,		/* for completeness */
+	fsa_R = 1,		/* read-only */
+	fsa_W = 2,		/* write-only */
+	fsa_RW = 3		/* read/write */
+};
+
+/*
+ * The following definitions come from the OpenNetworking
+ * Network Status Monitor protocol:
+ *
+ * https://pubs.opengroup.org/onlinepubs/9629799/chap11.htm
+ */
+
+const SM_MAXSTRLEN = 1024;
+
+/*
+ * The NLM protocol as extracted from:
+ * https://tools.ietf.org/html/rfc1813 Appendix II
+ */
+
+typedef unsigned hyper uint64;
+
+typedef hyper int64;
+
+typedef unsigned long uint32;
+
+typedef long int32;
+
+enum nlm4_stats {
+	NLM4_GRANTED = 0,
+	NLM4_DENIED = 1,
+	NLM4_DENIED_NOLOCKS = 2,
+	NLM4_BLOCKED = 3,
+	NLM4_DENIED_GRACE_PERIOD = 4,
+	NLM4_DEADLCK = 5,
+	NLM4_ROFS = 6,
+	NLM4_STALE_FH = 7,
+	NLM4_FBIG = 8,
+	NLM4_FAILED = 9
+};
+
+pragma big_endian nlm4_stats;
+
+struct nlm4_holder {
+	bool		exclusive;
+	int32		svid;
+	netobj		oh;
+	uint64		l_offset;
+	uint64		l_len;
+};
+
+union nlm4_testrply switch (nlm4_stats stat) {
+	case NLM4_DENIED:
+		nlm4_holder	holder;
+	default:
+		void;
+};
+
+struct nlm4_stat {
+	nlm4_stats	stat;
+};
+
+struct nlm4_res {
+	netobj		cookie;
+	nlm4_stat	stat;
+};
+
+struct nlm4_testres {
+	netobj		cookie;
+	nlm4_testrply	stat;
+};
+
+struct nlm4_lock {
+	string		caller_name<LM_MAXSTRLEN>;
+	netobj		fh;
+	netobj		oh;
+	int32		svid;
+	uint64		l_offset;
+	uint64		l_len;
+};
+
+struct nlm4_lockargs {
+	netobj		cookie;
+	bool		block;
+	bool		exclusive;
+	nlm4_lock	alock;
+	bool		reclaim;
+	int32		state;
+};
+
+struct nlm4_cancargs {
+	netobj		cookie;
+	bool		block;
+	bool		exclusive;
+	nlm4_lock	alock;
+};
+
+struct nlm4_testargs {
+	netobj		cookie;
+	bool		exclusive;
+	nlm4_lock	alock;
+};
+
+struct nlm4_unlockargs {
+	netobj		cookie;
+	nlm4_lock	alock;
+};
+
+struct nlm4_share {
+	string		caller_name<LM_MAXSTRLEN>;
+	netobj		fh;
+	netobj		oh;
+	fsh4_mode	mode;
+	fsh4_access	access;
+};
+
+struct nlm4_shareargs {
+	netobj		cookie;
+	nlm4_share	share;
+	bool		reclaim;
+};
+
+struct nlm4_shareres {
+	netobj		cookie;
+	nlm4_stats	stat;
+	int32		sequence;
+};
+
+struct nlm4_notify {
+	string		name<LM_MAXNAMELEN>;
+	int32		state;
+};
+
+/*
+ * Argument for the Linux-private SM_NOTIFY procedure
+ */
+const SM_PRIV_SIZE = 16;
+
+struct nlm4_notifyargs {
+	nlm4_notify	notify;
+	opaque		private[SM_PRIV_SIZE];
+};
+
+program NLM4_PROG {
+	version NLM4_VERS {
+		void		NLMPROC4_NULL(void)			= 0;
+		nlm4_testres	NLMPROC4_TEST(nlm4_testargs)		= 1;
+		nlm4_res	NLMPROC4_LOCK(nlm4_lockargs)		= 2;
+		nlm4_res	NLMPROC4_CANCEL(nlm4_cancargs)		= 3;
+		nlm4_res	NLMPROC4_UNLOCK(nlm4_unlockargs)	= 4;
+		nlm4_res	NLMPROC4_GRANTED(nlm4_testargs)		= 5;
+		void		NLMPROC4_TEST_MSG(nlm4_testargs)	= 6;
+		void		NLMPROC4_LOCK_MSG(nlm4_lockargs)	= 7;
+		void		NLMPROC4_CANCEL_MSG(nlm4_cancargs)	= 8;
+		void		NLMPROC4_UNLOCK_MSG(nlm4_unlockargs)	= 9;
+		void		NLMPROC4_GRANTED_MSG(nlm4_testargs)	= 10;
+		void		NLMPROC4_TEST_RES(nlm4_testres)		= 11;
+		void		NLMPROC4_LOCK_RES(nlm4_res)		= 12;
+		void		NLMPROC4_CANCEL_RES(nlm4_res)		= 13;
+		void		NLMPROC4_UNLOCK_RES(nlm4_res)		= 14;
+		void		NLMPROC4_GRANTED_RES(nlm4_res)		= 15;
+		void		NLMPROC4_SM_NOTIFY(nlm4_notifyargs)	= 16;
+		nlm4_shareres	NLMPROC4_SHARE(nlm4_shareargs)		= 20;
+		nlm4_shareres	NLMPROC4_UNSHARE(nlm4_shareargs)	= 21;
+		nlm4_res	NLMPROC4_NM_LOCK(nlm4_lockargs)		= 22;
+		void		NLMPROC4_FREE_ALL(nlm4_notify)		= 23;
+	} = 4;
+} = 100021;
diff --git a/Documentation/translations/it_IT/staging/magic-number.rst b/Documentation/translations/it_IT/staging/magic-number.rst
index cd8f235..43dd639 100644
--- a/Documentation/translations/it_IT/staging/magic-number.rst
+++ b/Documentation/translations/it_IT/staging/magic-number.rst
@@ -78,11 +78,8 @@
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/sp_SP/process/magic-number.rst b/Documentation/translations/sp_SP/process/magic-number.rst
index beb4b4c..f5b4c3f 100644
--- a/Documentation/translations/sp_SP/process/magic-number.rst
+++ b/Documentation/translations/sp_SP/process/magic-number.rst
@@ -77,11 +77,8 @@
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/zh_CN/infiniband/index.rst b/Documentation/translations/zh_CN/infiniband/index.rst
index 5634cc4..aeeea0b 100644
--- a/Documentation/translations/zh_CN/infiniband/index.rst
+++ b/Documentation/translations/zh_CN/infiniband/index.rst
@@ -24,7 +24,6 @@
 
    core_locking
    ipoib
-   opa_vnic
    sysfs
    tag_matching
    user_mad
diff --git a/Documentation/translations/zh_CN/infiniband/opa_vnic.rst b/Documentation/translations/zh_CN/infiniband/opa_vnic.rst
deleted file mode 100644
index 12b147f..0000000
--- a/Documentation/translations/zh_CN/infiniband/opa_vnic.rst
+++ /dev/null
@@ -1,156 +0,0 @@
-.. include:: ../disclaimer-zh_CN.rst
-
-:Original: Documentation/infiniband/opa_vnic.rst
-
-:翻译:
-
- 司延腾 Yanteng Si <siyanteng@loongson.cn>
-
-:校译:
-
- 王普宇 Puyu Wang <realpuyuwang@gmail.com>
- 时奎亮 Alex Shi <alexs@kernel.org>
-
-.. _cn_infiniband_opa_vnic:
-
-=============================================
-英特尔全路径(OPA)虚拟网络接口控制器(VNIC)
-=============================================
-
-英特尔全路径(OPA)虚拟网络接口控制器(VNIC)功能通过封装HFI节点之间的以
-太网数据包,支持Omni-Path结构上的以太网功能。
-
-体系结构
-========
-
-Omni-Path封装的以太网数据包的交换模式涉及Omni-Path结构拓扑上覆盖的一个或
-多个虚拟以太网交换机。Omni-Path结构上的HFI节点的一个子集被允许在特定的虚
-拟以太网交换机上交换封装的以太网数据包。虚拟以太网交换机是通过配置结构上的
-HFI节点实现的逻辑抽象,用于生成和处理报头。在最简单的配置中,整个结构的所有
-HFI节点通过一个虚拟以太网交换机交换封装的以太网数据包。一个虚拟以太网交换机,
-实际上是一个独立的以太网网络。该配置由以太网管理器(EM)执行,它是可信的结
-构管理器(FM)应用程序的一部分。HFI节点可以有多个VNIC,每个连接到不同的虚
-拟以太网交换机。下图介绍了两个虚拟以太网交换机与两个HFI节点的情况::
-
-                               +-------------------+
-                               |      子网/        |
-                               |     以太网        |
-                               |      管理         |
-                               +-------------------+
-                                  /          /
-                                /           /
-                              /            /
-                            /             /
-  +-----------------------------+  +------------------------------+
-  |     虚拟以太网切换          |  |      虚拟以太网切换          |
-  |  +---------+    +---------+ |  | +---------+    +---------+   |
-  |  | VPORT   |    |  VPORT  | |  | |  VPORT  |    |  VPORT  |   |
-  +--+---------+----+---------+-+  +-+---------+----+---------+---+
-           |                 \        /                 |
-           |                   \    /                   |
-           |                     \/                     |
-           |                    /  \                    |
-           |                  /      \                  |
-       +-----------+------------+  +-----------+------------+
-       |   VNIC    |    VNIC    |  |    VNIC   |    VNIC    |
-       +-----------+------------+  +-----------+------------+
-       |          HFI           |  |          HFI           |
-       +------------------------+  +------------------------+
-
-
-Omni-Path封装的以太网数据包格式如下所述。
-
-==================== ================================
-位                   域
-==================== ================================
-Quad Word 0:
-0-19                 SLID (低20位)
-20-30                长度 (以四字为单位)
-31                   BECN 位
-32-51                DLID (低20位)
-52-56                SC (服务级别)
-57-59                RC (路由控制)
-60                   FECN 位
-61-62                L2 (=10, 16B 格式)
-63                   LT (=1, 链路传输头 Flit)
-
-Quad Word 1:
-0-7                  L4 type (=0x78 ETHERNET)
-8-11                 SLID[23:20]
-12-15                DLID[23:20]
-16-31                PKEY
-32-47                熵
-48-63                保留
-
-Quad Word 2:
-0-15                 保留
-16-31                L4 头
-32-63                以太网数据包
-
-Quad Words 3 to N-1:
-0-63                 以太网数据包 (pad拓展)
-
-Quad Word N (last):
-0-23                 以太网数据包 (pad拓展)
-24-55                ICRC
-56-61                尾
-62-63                LT (=01, 链路传输尾 Flit)
-==================== ================================
-
-以太网数据包在传输端被填充,以确保VNIC OPA数据包是四字对齐的。“尾”字段
-包含填充的字节数。在接收端,“尾”字段被读取,在将数据包向上传递到网络堆
-栈之前,填充物被移除(与ICRC、尾和OPA头一起)。
-
-L4头字段包含VNIC端口所属的虚拟以太网交换机ID。在接收端,该字段用于将收
-到的VNIC数据包去多路复用到不同的VNIC端口。
-
-驱动设计
-========
-
-英特尔OPA VNIC的软件设计如下图所示。OPA VNIC功能有一个依赖于硬件的部分
-和一个独立于硬件的部分。
-
-对IB设备分配和释放RDMA netdev设备的支持已经被加入。RDMA netdev支持与
-网络堆栈的对接,从而创建标准的网络接口。OPA_VNIC是一个RDMA netdev设备
-类型。
-
-依赖于HW的VNIC功能是HFI1驱动的一部分。它实现了分配和释放OPA_VNIC RDMA
-netdev的动作。它涉及VNIC功能的HW资源分配/管理。它与网络堆栈接口并实现所
-需的net_device_ops功能。它在传输路径中期待Omni-Path封装的以太网数据包,
-并提供对它们的HW访问。在将数据包向上传递到网络堆栈之前,它把Omni-Path头
-从接收的数据包中剥离。它还实现了RDMA netdev控制操作。
-
-OPA VNIC模块实现了独立于硬件的VNIC功能。它由两部分组成。VNIC以太网管理
-代理(VEMA)作为一个IB客户端向IB核心注册,并与IB MAD栈接口。它与以太网
-管理器(EM)和VNIC netdev交换管理信息。VNIC netdev部分分配和释放OPA_VNIC
-RDMA netdev设备。它在需要时覆盖由依赖HW的VNIC驱动设置的net_device_ops函数,
-以适应任何控制操作。它还处理以太网数据包的封装,在传输路径中使用Omni-Path头。
-对于每个VNIC接口,封装所需的信息是由EM通过VEMA MAD接口配置的。它还通过调用
-RDMA netdev控制操作将任何控制信息传递给依赖于HW的驱动程序::
-
-        +-------------------+ +----------------------+
-        |                   | |       Linux          |
-        |     IB MAD        | |       网络           |
-        |                   | |       栈             |
-        +-------------------+ +----------------------+
-                 |               |          |
-                 |               |          |
-        +----------------------------+      |
-        |                            |      |
-        |      OPA VNIC 模块         |      |
-        |  (OPA VNIC RDMA Netdev     |      |
-        |     & EMA 函数)            |      |
-        |                            |      |
-        +----------------------------+      |
-                    |                       |
-                    |                       |
-           +------------------+             |
-           |     IB 核心      |             |
-           +------------------+             |
-                    |                       |
-                    |                       |
-        +--------------------------------------------+
-        |                                            |
-        |      HFI1 驱动和 VNIC 支持                 |
-        |                                            |
-        +--------------------------------------------+
diff --git a/Documentation/translations/zh_CN/networking/index.rst b/Documentation/translations/zh_CN/networking/index.rst
index c276c09..333e9f6 100644
--- a/Documentation/translations/zh_CN/networking/index.rst
+++ b/Documentation/translations/zh_CN/networking/index.rst
@@ -42,7 +42,6 @@
 *   diagnostic/index
 *   dsa/index
 *   devlink/index
-*   caif/index
 *   ethtool-netlink
 *   ieee802154
 *   iso15765-2
diff --git a/Documentation/translations/zh_CN/process/magic-number.rst b/Documentation/translations/zh_CN/process/magic-number.rst
index 4ebc84c..05ee75c 100644
--- a/Documentation/translations/zh_CN/process/magic-number.rst
+++ b/Documentation/translations/zh_CN/process/magic-number.rst
@@ -70,11 +70,8 @@
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/translations/zh_TW/process/magic-number.rst b/Documentation/translations/zh_TW/process/magic-number.rst
index 5582df6..bc7eb025 100644
--- a/Documentation/translations/zh_TW/process/magic-number.rst
+++ b/Documentation/translations/zh_TW/process/magic-number.rst
@@ -64,11 +64,8 @@
 APM_BIOS_MAGIC        0x4101           apm_user                 ``arch/x86/kernel/apm_32.c``
 FASYNC_MAGIC          0x4601           fasync_struct            ``include/linux/fs.h``
 SLIP_MAGIC            0x5302           slip                     ``drivers/net/slip.h``
-BAYCOM_MAGIC          0x19730510       baycom_state             ``drivers/net/baycom_epp.c``
-HDLCDRV_MAGIC         0x5ac6e778       hdlcdrv_state            ``include/linux/hdlcdrv.h``
 KV_MAGIC              0x5f4b565f       kernel_vars_s            ``arch/mips/include/asm/sn/klkernvars.h``
 CODA_MAGIC            0xC0DAC0DA       coda_file_info           ``fs/coda/coda_fs_i.h``
-YAM_MAGIC             0xF10A7654       yam_port                 ``drivers/net/hamradio/yam.c``
 CCB_MAGIC             0xf2691ad2       ccb                      ``drivers/scsi/ncr53c8xx.c``
 QUEUE_MAGIC_FREE      0xf7e1c9a3       queue_entry              ``drivers/scsi/arm/queue.c``
 QUEUE_MAGIC_USED      0xf7e1cc33       queue_entry              ``drivers/scsi/arm/queue.c``
diff --git a/Documentation/wmi/devices/bitland-mifs-wmi.rst b/Documentation/wmi/devices/bitland-mifs-wmi.rst
new file mode 100644
index 0000000..9e86ecc
--- /dev/null
+++ b/Documentation/wmi/devices/bitland-mifs-wmi.rst
@@ -0,0 +1,207 @@
+.. SPDX-License-Identifier: GPL-2.0-or-later
+
+========================================
+Bitland MIFS driver (bitland-mifs-wmi)
+========================================
+
+Introduction
+============
+
+
+EC WMI interface description
+============================
+
+The EC WMI interface description can be decoded from the embedded binary MOF (bmof)
+data using the `bmfdec <https://github.com/pali/bmfdec>`_ utility:
+
+::
+
+  class WMIEvent : __ExtrinsicEvent {
+  };
+
+  [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT20"), guid("{46c93e13-ee9b-4262-8488-563bca757fef}")]
+  class HID_EVENT20 : WmiEvent {
+    [key, read] string InstanceName;
+    [read] boolean Active;
+    [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
+  };
+
+  [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT21"), guid("{fa78e245-2c0f-4ca1-91cf-15f34e474850}")]
+  class HID_EVENT21 : WmiEvent {
+    [key, read] string InstanceName;
+    [read] boolean Active;
+    [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
+  };
+
+  [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT22"), guid("{1dceaf0a-4d63-44bb-bd0c-0d6281bfddc5}")]
+  class HID_EVENT22 : WmiEvent {
+    [key, read] string InstanceName;
+    [read] boolean Active;
+    [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
+  };
+
+  [WMI, Dynamic, Provider("WmiProv"), Locale("MS\\0x40A"), Description("Root WMI HID_EVENT23"), guid("{3f9e3c26-b077-4f86-91f5-37ff64d8c7ed}")]
+  class HID_EVENT23 : WmiEvent {
+    [key, read] string InstanceName;
+    [read] boolean Active;
+    [WmiDataId(1), read, write, Description("Package Data")] uint8 EventDetail[8];
+  };
+
+  [WMI, Dynamic, provider("WmiProv"), Locale("MS\\0x409"), Description("Class used to operate firmware interface"), guid("{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}")]
+  class MICommonInterface {
+    [key, read] string InstanceName;
+    [read] boolean Active;
+
+    [WmiMethodId(1), Implemented, read, write, Description("Method used to support system functions.")] void MiInterface([in, Description("WMI Interface")] uint8 InData[32], [out] uint8 OutData[30], [out] uint16 Reserved);
+  };
+
+Reverse-Engineering the EC WMI interface
+========================================
+
+The OEM software can be download from `this link <https://iknow.lenovo.com.cn/detail/429447>`_
+
+Nothing is obfuscated, In this case, `ILSpy <https://github.com/icsharpcode/ILSpy>`_ could be helpful.
+
+WMI Methods (MICommonInterface)
+========================================
+
+The ``MICommonInterface`` class (GUID: ``{b60bfb48-3e5b-49e4-a0e9-8cffe1b3434b}``)
+is the primary control interface. It uses a 32-byte buffer for both input
+(``InData``) and output (``OutData``).
+
+Method Structure
+----------------
+
+The data packet follows a standardized format:
+
++----------+------------------------------------------------------------------+
+| Byte     | Description                                                      |
++==========+==================================================================+
+| 1        | Method Type: Get (0xFA / 250) or Set (0xFB / 251)                |
++----------+------------------------------------------------------------------+
+| 3        | Command ID (Method Name)                                         |
++----------+------------------------------------------------------------------+
+| 4 - 31   | Arguments (for Set) or Return Data (for Get)                     |
++----------+------------------------------------------------------------------+
+
+
+Command IDs
+-----------
+
+The following Command IDs are used in the third byte of the buffer:
+
++----------+-----------------------+------------------------------------------+
+| ID       | Name                  | Values / Description                     |
++==========+=======================+==========================================+
+| 8        | SystemPerMode         | 0: Balance, 1: Performance, 2: Quiet,    |
+|          |                       | 3: Full-speed                            |
++----------+-----------------------+------------------------------------------+
+| 9        | GPUMode               | 0: Hybrid, 1: Discrete, 2: UMA           |
++----------+-----------------------+------------------------------------------+
+| 10       | KeyboardType          | 0: White, 1: Single RGB, 2: Zone RGB     |
++----------+-----------------------+------------------------------------------+
+| 11       | FnLock                | 0: Off, 1: On                            |
++----------+-----------------------+------------------------------------------+
+| 12       | TPLock                | 0: Unlock, 1: Lock (Touchpad)            |
++----------+-----------------------+------------------------------------------+
+| 13       | CPUGPUSYSFanSpeed     | Returns 12 bytes of fan data:            |
+|          |                       | Bytes 4-5: CPU Fan RPM (Little Endian)   |
+|          |                       | Bytes 6-7: GPU Fan RPM (Little Endian)   |
+|          |                       | Bytes 10-11: SYS Fan RPM (Little Endian) |
++----------+-----------------------+------------------------------------------+
+| 16       | RGBKeyboardMode       | 0: Off, 1: Auto Cyclic, 2: Fixed,        |
+|          |                       | 3: Custom                                |
++----------+-----------------------+------------------------------------------+
+| 17       | RGBKeyboardColor      | Bytes 4, 5, 6: Red, Green, Blue values   |
++----------+-----------------------+------------------------------------------+
+| 18       | RGBKeyboardBrightness | 0-10: Brightness Levels, 128: Auto       |
++----------+-----------------------+------------------------------------------+
+| 19       | SystemAcType          | 1: Type-C, 2: Circular Hole (DC)         |
++----------+-----------------------+------------------------------------------+
+| 20       | MaxFanSpeedSwitch     | Byte 4: Fan Type (0: CPU/GPU, 1: SYS)    |
+|          |                       | Byte 5: State (0: Off, 1: On)            |
++----------+-----------------------+------------------------------------------+
+| 21       | MaxFanSpeed           | Sets manual fan speed duty cycle         |
++----------+-----------------------+------------------------------------------+
+| 22       | CPUThermometer        | Returns CPU Temperature                  |
++----------+-----------------------+------------------------------------------+
+
+WMI Events (HID_EVENT20)
+========================
+
+The driver listens for events from the ``HID_EVENT20`` class
+(GUID: ``{46c93e13-ee9b-4262-8488-563bca757fef}``). These events are triggered
+by hotkeys or system state changes (e.g., plugging in AC power).
+
+Event Structure
+---------------
+
+The event data is provided in an 8-byte array (``EventDetail``):
+
++----------+------------------------------------------------------------------+
+| Byte     | Description                                                      |
++==========+==================================================================+
+| 0        | Event Type (Always 0x01 for HotKey/Notification)                 |
++----------+------------------------------------------------------------------+
+| 1        | Event ID (Corresponds to the Command IDs above)                  |
++----------+------------------------------------------------------------------+
+| 2        | Value (The new state or value of the feature)                    |
++----------+------------------------------------------------------------------+
+
+Common Event IDs:
+-----------------
+
+Note: reserved event ids are not listed there
+
++----------+------------------------------------------------------------------+
+| Event Id | Description                                                      |
++==========+==================================================================+
+| 4        | AirPlane mode change                                             |
++----------+------------------------------------------------------------------+
+| 5        | Keyboard brightness change                                       |
++----------+------------------------------------------------------------------+
+| 6        | Touchpad state (enabled/disabled) change                         |
++----------+------------------------------------------------------------------+
+| 7        | FnLock state (enabled/disabled) change                           |
++----------+------------------------------------------------------------------+
+| 8        | Keyboard mode change                                             |
++----------+------------------------------------------------------------------+
+| 9        | CapsLock state change                                            |
++----------+------------------------------------------------------------------+
+| 13       | NumLock state change                                             |
++----------+------------------------------------------------------------------+
+| 14       | ScrollLock state change                                          |
++----------+------------------------------------------------------------------+
+| 15       | Performance plan change                                          |
++----------+------------------------------------------------------------------+
+| 25       | Display refresh rate change                                      |
++----------+------------------------------------------------------------------+
+| 33       | Super key lock state (enabled/disabled) change                   |
++----------+------------------------------------------------------------------+
+| 35       | Open control center key                                          |
++----------+------------------------------------------------------------------+
+
+Implementation Details
+======================
+
+Performance Modes
+-----------------
+Changing the performance mode via Command ID 0x08 (SystemPerMode) affects the
+power limits (PL1/PL2) and fan curves managed by the Embedded Controller (EC).
+Note that the "Full-speed" and "Performance" mode (1, 3) is typically only
+available when the system is connected to a DC power source (not USB-C/PD).
+
+In the driver implementation, switch to performance/full-speed mode without
+DC power connected will throw the EOPNOTSUPP error.
+
+Graphics Switching
+------------------
+The ``GPUMode`` (0x09) allows switching between Hybrid (Muxless) and Discrete
+(Muxed) graphics. Changing this value usually requires a system reboot to
+take effect in the BIOS/Firmware.
+
+Fan Control
+-----------
+The system supports both automatic EC control and manual overrides. Command ID
+0x14 (``MaxFanSpeedSwitch``) is used to toggle manual control, while ID 0x15
+sets the actual PWM duty cycle.
diff --git a/Documentation/wmi/driver-development-guide.rst b/Documentation/wmi/driver-development-guide.rst
index fbc2d9b..387f508 100644
--- a/Documentation/wmi/driver-development-guide.rst
+++ b/Documentation/wmi/driver-development-guide.rst
@@ -71,7 +71,7 @@
         .remove = foo_remove,         /* optional, devres is preferred */
         .shutdown = foo_shutdown,     /* optional, called during shutdown */
         .notify_new = foo_notify,     /* optional, for event handling */
-        .no_notify_data = true,       /* optional, enables events containing no additional data */
+        .min_event_size = X,          /* optional, simplifies event payload size verification */
         .no_singleton = true,         /* required for new WMI drivers */
   };
   module_wmi_driver(foo_driver);
@@ -106,7 +106,8 @@
 
 WMI drivers can call WMI device methods using wmidev_invoke_method(). For each WMI method
 invocation the WMI driver needs to provide the instance number and the method ID, as well as
-a buffer with the method arguments and optionally a buffer for the results.
+a buffer with the method arguments and optionally a buffer for the results. When calling WMI
+methods that do not return any values, wmidev_invoke_procedure() should be used instead.
 
 The layout of said buffers is device-specific and described by the Binary MOF data associated
 with a given WMI device. Said Binary MOF data also describes the method ID of a given WMI method
@@ -141,8 +142,10 @@
 However WMI driver developers should be aware that multiple WMI events can be received concurrently,
 so any locking (if necessary) needs to be provided by the WMI driver itself.
 
-In order to be able to receive WMI events containing no additional event data,
-the ``no_notify_data`` flag inside struct wmi_driver should be set to ``true``.
+The WMI driver can furthermore instruct the WMI driver core to automatically reject WMI events
+that contain a undersized event payload by populating the ``min_event_size`` field inside
+struct wmi_driver. Setting this field to 0 will thus enable the WMI driver to receive WMI events
+without any event payload.
 
 Take a look at drivers/platform/x86/xiaomi-wmi.c for an example WMI event driver.
 
diff --git a/MAINTAINERS b/MAINTAINERS
index 13f4937..2fb1c75 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -103,12 +103,6 @@
 F:	include/net/6lowpan.h
 F:	net/6lowpan/
 
-6PACK NETWORK DRIVER FOR AX.25
-M:	Andreas Koensgen <ajk@comnets.uni-bremen.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-F:	drivers/net/hamradio/6pack.c
-
 802.11 (including CFG80211/NL80211)
 M:	Johannes Berg <johannes@sipsolutions.net>
 L:	linux-wireless@vger.kernel.org
@@ -144,7 +138,7 @@
 F:	drivers/tty/serial/8250*
 F:	include/linux/serial_8250.h
 
-8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
+8390 NETWORK DRIVERS [NE2000, 3C503, etc.]
 L:	netdev@vger.kernel.org
 S:	Orphan / Obsolete
 F:	drivers/net/ethernet/8390/
@@ -646,8 +640,11 @@
 F:	Documentation/devicetree/bindings/iio/accel/adi,adxl367.yaml
 F:	drivers/iio/accel/adxl367*
 
-ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
+ADXL371/ADXL372 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
 M:	Michael Hennerich <michael.hennerich@analog.com>
+M:	Marcelo Schmitt <marcelo.schmitt@analog.com>
+M:	Nuno Sá <nuno.sa@analog.com>
+M:	Antoniu Miclaus <antoniu.miclaus@analog.com>
 S:	Supported
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/devicetree/bindings/iio/accel/adi,adxl372.yaml
@@ -1588,6 +1585,15 @@
 F:	Documentation/devicetree/bindings/iio/adc/adi,ad7780.yaml
 F:	drivers/iio/adc/ad7780.c
 
+ANALOG DEVICES INC AD8366 DRIVER
+M:	Michael Hennerich <Michael.Hennerich@analog.com>
+M:	Rodrigo Alencar <rodrigo.alencar@analog.com>
+L:	linux-iio@vger.kernel.org
+S:	Supported
+W:	https://ez.analog.com/linux-software-drivers
+F:	Documentation/devicetree/bindings/iio/amplifiers/adi,ad8366.yaml
+F:	drivers/iio/amplifiers/ad8366.c
+
 ANALOG DEVICES INC AD9467 DRIVER
 M:	Michael Hennerich <Michael.Hennerich@analog.com>
 M:	Nuno Sa <nuno.sa@analog.com>
@@ -1696,6 +1702,14 @@
 W:	https://ez.analog.com/linux-software-drivers
 F:	Documentation/devicetree/bindings/iio/imu/adi,adis16550.yaml
 
+ANALOG DEVICES INC ADL8113 DRIVER
+M:	Antoniu Miclaus <antoniu.miclaus@analog.com>
+L:	linux-iio@vger.kernel.org
+S:	Supported
+W:	https://ez.analog.com/linux-software-drivers
+F:	Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml
+F:	drivers/iio/amplifiers/adl8113.c
+
 ANALOG DEVICES INC ADM1177 DRIVER
 M:	Michael Hennerich <Michael.Hennerich@analog.com>
 L:	linux-hwmon@vger.kernel.org
@@ -2706,8 +2720,9 @@
 
 ARM/CORESIGHT FRAMEWORK AND DRIVERS
 M:	Suzuki K Poulose <suzuki.poulose@arm.com>
-R:	Mike Leach <mike.leach@linaro.org>
+R:	Mike Leach <mike.leach@arm.com>
 R:	James Clark <james.clark@linaro.org>
+R:	Leo Yan <leo.yan@arm.com>
 L:	coresight@lists.linaro.org (moderated for non-subscribers)
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Maintained
@@ -4158,10 +4173,12 @@
 S:	Maintained
 W:	http://linux-atm.sourceforge.net
 F:	drivers/atm/
+F:	drivers/usb/atm/
 F:	include/linux/atm*
 F:	include/linux/sonet.h
 F:	include/uapi/linux/atm*
 F:	include/uapi/linux/sonet.h
+F:	net/atm/
 
 ATMEL MACB ETHERNET DRIVER
 M:	Nicolas Ferre <nicolas.ferre@microchip.com>
@@ -4281,14 +4298,6 @@
 F:	Documentation/devicetree/bindings/leds/backlight/awinic,aw99706.yaml
 F:	drivers/video/backlight/aw99706.c
 
-AX.25 NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/ax25.h
-F:	include/uapi/linux/ax25.h
-F:	net/ax25/
-
 AXENTIA ARM DEVICES
 M:	Peter Rosin <peda@axentia.se>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -4430,13 +4439,6 @@
 F:	include/uapi/linux/batman_adv.h
 F:	net/batman-adv/
 
-BAYCOM/HDLCDRV DRIVERS FOR AX.25
-M:	Thomas Sailer <t.sailer@alumni.ethz.ch>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://www.baycom.org/~tom/ham/ham.html
-F:	drivers/net/hamradio/baycom*
-
 BCACHE (BLOCK LAYER CACHE)
 M:	Coly Li <colyli@fnnas.com>
 M:	Kent Overstreet <kent.overstreet@linux.dev>
@@ -5675,15 +5677,6 @@
 F:	Documentation/admin-guide/media/cafe_ccic*
 F:	drivers/media/platform/marvell/
 
-CAIF NETWORK LAYER
-L:	netdev@vger.kernel.org
-S:	Orphan
-F:	Documentation/networking/caif/
-F:	drivers/net/caif/
-F:	include/net/caif/
-F:	include/uapi/linux/caif/
-F:	net/caif/
-
 CAKE QDISC
 M:	Toke Høiland-Jørgensen <toke@toke.dk>
 L:	cake@lists.bufferbloat.net (moderated for non-subscribers)
@@ -5959,6 +5952,13 @@
 F:	Documentation/hwmon/powerz.rst
 F:	drivers/hwmon/powerz.c
 
+CHARLIEPLEX KEYPAD DRIVER
+M:	Hugo Villeneuve <hvilleneuve@dimonoff.com>
+S:	Supported
+W:	http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/electronic-circuits/matrix-keypad-scan-decode
+F:	Documentation/devicetree/bindings/input/gpio-charlieplex-keypad.yaml
+F:	drivers/input/keyboard/charlieplex_keypad.c
+
 CHECKPATCH
 M:	Andy Whitcroft <apw@canonical.com>
 M:	Joe Perches <joe@perches.com>
@@ -7023,20 +7023,6 @@
 F:	drivers/rtc/rtc-ds1685.c
 F:	include/linux/rtc/ds1685.h
 
-DAMA SLAVE for AX.25
-M:	Joerg Reuter <jreuter@yaina.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://yaina.de/jreuter/
-W:	http://www.qsl.net/dl1bke/
-F:	net/ax25/af_ax25.c
-F:	net/ax25/ax25_dev.c
-F:	net/ax25/ax25_ds_*
-F:	net/ax25/ax25_in.c
-F:	net/ax25/ax25_out.c
-F:	net/ax25/ax25_timer.c
-F:	net/ax25/sysctl_net_ax25.c
-
 DASHARO ACPI PLATFORM DRIVER
 M:	Michał Kopeć <michal.kopec@3mdeb.com>
 S:	Maintained
@@ -7303,6 +7289,14 @@
 S:	Supported
 F:	drivers/dax/
 
+DEVICE DIRECT ACCESS (DAX) [fsdev_dax]
+M:	John Groves <jgroves@micron.com>
+M:	John Groves <John@Groves.net>
+L:	nvdimm@lists.linux.dev
+L:	linux-cxl@vger.kernel.org
+S:	Supported
+F:	drivers/dax/fsdev.c
+
 DEVICE FREQUENCY (DEVFREQ)
 M:	MyungJoo Ham <myungjoo.ham@samsung.com>
 M:	Kyungmin Park <kyungmin.park@samsung.com>
@@ -8629,10 +8623,17 @@
 T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
 F:	drivers/gpu/drm/gma500/
 
-DRM DRIVERS FOR HISILICON
-M:	Xinliang Liu <xinliang.liu@linaro.org>
+DRM DRIVERS FOR HISILICON HIBMC
+M:	Yongbang Shi <shiyongbang@huawei.com>
 M:	Tian Tao  <tiantao6@hisilicon.com>
 R:	Xinwei Kong <kong.kongxinwei@hisilicon.com>
+L:	dri-devel@lists.freedesktop.org
+S:	Maintained
+T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
+F:	drivers/gpu/drm/hisilicon/hibmc
+
+DRM DRIVERS FOR HISILICON KIRIN
+M:	Xinliang Liu <xinliang.liu@linaro.org>
 R:	Sumit Semwal <sumit.semwal@linaro.org>
 R:	Yongqin Liu <yongqin.liu@linaro.org>
 R:	John Stultz <jstultz@google.com>
@@ -8640,7 +8641,7 @@
 S:	Maintained
 T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
 F:	Documentation/devicetree/bindings/display/hisilicon/
-F:	drivers/gpu/drm/hisilicon/
+F:	drivers/gpu/drm/hisilicon/kirin
 
 DRM DRIVERS FOR LIMA
 M:	Qiang Yu <yuq825@gmail.com>
@@ -8691,7 +8692,7 @@
 F:	include/uapi/drm/tegra_drm.h
 
 DRM DRIVERS FOR PRE-DCP APPLE DISPLAY OUTPUT
-M:	Sasha Finkelstein <fnkl.kernel@gmail.com>
+M:	Sasha Finkelstein <k@chaosmail.tech>
 R:	Janne Grunau <j@jannau.net>
 L:	dri-devel@lists.freedesktop.org
 L:	asahi@lists.linux.dev
@@ -9139,6 +9140,8 @@
 F:	arch/mips/econet/
 F:	drivers/clocksource/timer-econet-en751221.c
 F:	drivers/irqchip/irq-econet-en751221.c
+F:	include/dt-bindings/clock/econet,en751221-scu.h
+F:	include/dt-bindings/reset/econet,en751221-scu.h
 
 ECRYPT FILE SYSTEM
 M:	Tyler Hicks <code@tyhicks.com>
@@ -9538,6 +9541,14 @@
 F:	Documentation/devicetree/bindings/riscv/eswin.yaml
 F:	arch/riscv/boot/dts/eswin/
 
+ESWIN EIC7700 CLOCK DRIVER
+M:	Yifeng Huang <huangyifeng@eswincomputing.com>
+M:	Xuyang Dong <dongxuyang@eswincomputing.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/clock/eswin,eic7700-clock.yaml
+F:	drivers/clk/eswin/
+F:	include/dt-bindings/clock/eswin,eic7700-clock.h
+
 ET131X NETWORK DRIVER
 M:	Mark Einon <mark.einon@gmail.com>
 S:	Odd Fixes
@@ -11498,11 +11509,6 @@
 F:	rust/kernel/time.rs
 F:	rust/kernel/time/
 
-HIGH-SPEED SCC DRIVER FOR AX.25
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-F:	drivers/net/hamradio/scc.c
-
 HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
 M:	HighPoint Linux Team <linux@highpoint-tech.com>
 S:	Supported
@@ -12090,11 +12096,12 @@
 F:	include/uapi/linux/i2c.h
 
 I2C SUBSYSTEM [RUST]
-M:	Igor Korotin <igor.korotin.linux@gmail.com>
+M:	Igor Korotin <igor.korotin@linux.dev>
 R:	Danilo Krummrich <dakr@kernel.org>
 R:	Daniel Almeida <daniel.almeida@collabora.com>
 L:	rust-for-linux@vger.kernel.org
 S:	Maintained
+T:	git https://github.com/ikrtn/linux.git rust-i2c-next
 F:	rust/kernel/i2c.rs
 F:	samples/rust/rust_driver_i2c.rs
 F:	samples/rust/rust_i2c_client.rs
@@ -12619,6 +12626,7 @@
 F:	include/uapi/rdma/
 F:	samples/bpf/ibumad_kern.c
 F:	samples/bpf/ibumad_user.c
+F:	tools/testing/selftests/rdma/
 
 INGENIC JZ4780 NAND DRIVER
 M:	Harvey Hunt <harveyhuntnexus@gmail.com>
@@ -13393,6 +13401,12 @@
 F:	include/linux/interconnect-provider.h
 F:	include/linux/interconnect.h
 
+INTERCONNECT KUNIT TESTS
+M:	Kuan-Wei Chiu <visitorckw@gmail.com>
+L:	linux-pm@vger.kernel.org
+S:	Maintained
+F:	drivers/interconnect/icc-kunit.c
+
 INTERRUPT COUNTER DRIVER
 M:	Oleksij Rempel <o.rempel@pengutronix.de>
 R:	Pengutronix Kernel Team <kernel@pengutronix.de>
@@ -13650,25 +13664,6 @@
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending.git master
 F:	drivers/infiniband/ulp/isert
 
-ISDN/CMTP OVER BLUETOOTH
-L:	netdev@vger.kernel.org
-S:	Orphan
-W:	http://www.isdn4linux.de
-F:	Documentation/isdn/
-F:	drivers/isdn/capi/
-F:	include/linux/isdn/
-F:	include/uapi/linux/isdn/
-F:	net/bluetooth/cmtp/
-
-ISDN/mISDN SUBSYSTEM
-L:	netdev@vger.kernel.org
-S:	Orphan
-W:	http://www.isdn4linux.de
-F:	drivers/isdn/Kconfig
-F:	drivers/isdn/Makefile
-F:	drivers/isdn/hardware/
-F:	drivers/isdn/mISDN/
-
 ISL28022 HARDWARE MONITORING DRIVER
 M:	Carsten Spieß <mail@carsten-spiess.de>
 L:	linux-hwmon@vger.kernel.org
@@ -13859,8 +13854,10 @@
 KDUMP
 M:	Andrew Morton <akpm@linux-foundation.org>
 M:	Baoquan He <bhe@redhat.com>
-R:	Vivek Goyal <vgoyal@redhat.com>
-R:	Dave Young <dyoung@redhat.com>
+M:	Mike Rapoport <rppt@kernel.org>
+M:	Pasha Tatashin <pasha.tatashin@soleen.com>
+M:	Pratyush Yadav <pratyush@kernel.org>
+R:	Dave Young <ruirui.yang@linux.dev>
 L:	kexec@lists.infradead.org
 S:	Maintained
 W:	http://lse.sourceforge.net/kdump/
@@ -14175,6 +14172,9 @@
 KEXEC
 M:	Andrew Morton <akpm@linux-foundation.org>
 M:	Baoquan He <bhe@redhat.com>
+M:	Mike Rapoport <rppt@kernel.org>
+M:	Pasha Tatashin <pasha.tatashin@soleen.com>
+M:	Pratyush Yadav <pratyush@kernel.org>
 L:	kexec@lists.infradead.org
 W:	http://kernel.org/pub/linux/utils/kernel/kexec/
 F:	include/linux/kexec.h
@@ -14182,18 +14182,18 @@
 F:	kernel/kexec*
 
 KEXEC HANDOVER (KHO)
-M:	Alexander Graf <graf@amazon.com>
 M:	Mike Rapoport <rppt@kernel.org>
 M:	Pasha Tatashin <pasha.tatashin@soleen.com>
-R:	Pratyush Yadav <pratyush@kernel.org>
+M:	Pratyush Yadav <pratyush@kernel.org>
+R:	Alexander Graf <graf@amazon.com>
 L:	kexec@lists.infradead.org
 L:	linux-mm@kvack.org
 S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
 F:	Documentation/admin-guide/mm/kho.rst
 F:	Documentation/core-api/kho/*
 F:	include/linux/kexec_handover.h
 F:	include/linux/kho/
-F:	include/linux/kho/abi/
 F:	kernel/liveupdate/kexec_handover*
 F:	lib/test_kho.c
 F:	tools/testing/selftests/kho/
@@ -14892,15 +14892,15 @@
 LIVE UPDATE
 M:	Pasha Tatashin <pasha.tatashin@soleen.com>
 M:	Mike Rapoport <rppt@kernel.org>
-R:	Pratyush Yadav <pratyush@kernel.org>
+M:	Pratyush Yadav <pratyush@kernel.org>
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/liveupdate/linux.git
 F:	Documentation/core-api/liveupdate.rst
 F:	Documentation/mm/memfd_preservation.rst
 F:	Documentation/userspace-api/liveupdate.rst
 F:	include/linux/kho/abi/
 F:	include/linux/liveupdate.h
-F:	include/linux/liveupdate/
 F:	include/uapi/linux/liveupdate.h
 F:	kernel/liveupdate/
 F:	lib/tests/liveupdate.c
@@ -15305,6 +15305,13 @@
 W:	http://www.tazenda.demon.co.uk/phil/linux-hp
 F:	arch/m68k/hp300/
 
+M68K ON MVME147
+M:	Daniel Palmer <daniel@thingy.jp>
+S:	Maintained
+F:	arch/m68k/mvme147/
+F:	drivers/net/ethernet/amd/mvme147.c
+F:	drivers/scsi/mvme147.*
+
 M88DS3103 MEDIA DRIVER
 L:	linux-media@vger.kernel.org
 S:	Orphan
@@ -15811,6 +15818,12 @@
 F:	drivers/nvmem/max77759-nvmem.c
 F:	include/linux/mfd/max77759.h
 
+MAXIM MAX77759 BATTERY CHARGER DRIVER
+M:	Amit Sunil Dhamne <amitsd@google.com>
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+F:	drivers/power/supply/max77759_charger.c
+
 MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER
 M:	Javier Martinez Canillas <javier@dowhile0.org>
 L:	linux-kernel@vger.kernel.org
@@ -16859,8 +16872,12 @@
 
 MEMORY MANAGEMENT - MGLRU (MULTI-GEN LRU)
 M:	Andrew Morton <akpm@linux-foundation.org>
-M:	Axel Rasmussen <axelrasmussen@google.com>
-M:	Yuanchu Xie <yuanchu@google.com>
+R:	Kairui Song <kasong@tencent.com>
+R:	Qi Zheng <qi.zheng@linux.dev>
+R:	Shakeel Butt <shakeel.butt@linux.dev>
+R:	Barry Song <baohua@kernel.org>
+R:	Axel Rasmussen <axelrasmussen@google.com>
+R:	Yuanchu Xie <yuanchu@google.com>
 R:	Wei Xu <weixugc@google.com>
 L:	linux-mm@kvack.org
 S:	Maintained
@@ -18393,14 +18410,6 @@
 F:	net/netfilter/
 F:	tools/testing/selftests/net/netfilter/
 
-NETROM NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/netrom.h
-F:	include/uapi/linux/netrom.h
-F:	net/netrom/
-
 NETRONIX EMBEDDED CONTROLLER
 M:	Jonathan Neuschäfer <j.neuschaefer@gmx.net>
 S:	Maintained
@@ -19063,7 +19072,7 @@
 M:	Kai-Heng Feng <kaihengf@nvidia.com>
 L:	linux-acpi@vger.kernel.org
 S:	Maintained
-F:	drivers/acpi/apei/nvidia-ghes.c
+F:	drivers/acpi/apei/ghes-nvidia.c
 
 NVIDIA VRS RTC DRIVER
 M:	Shubhi Garg <shgarg@nvidia.com>
@@ -19391,8 +19400,8 @@
 F:	include/linux/mfd/ocelot.h
 
 OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
-M:	Frederic Barrat <fbarrat@linux.ibm.com>
-M:	Andrew Donnellan <ajd@linux.ibm.com>
+M:	Mahesh J Salgaonkar <mahesh@linux.ibm.com>
+R:	Andrew Donnellan <andrew+kernel@donnellan.id.au>
 L:	linuxppc-dev@lists.ozlabs.org
 S:	Odd Fixes
 F:	Documentation/userspace-api/accelerators/ocxl.rst
@@ -19917,12 +19926,6 @@
 S:	Maintained
 F:	drivers/rtc/rtc-optee.c
 
-OPA-VNIC DRIVER
-M:	Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
-L:	linux-rdma@vger.kernel.org
-S:	Supported
-F:	drivers/infiniband/ulp/opa_vnic
-
 OPEN ALLIANCE 10BASE-T1S MACPHY SERIAL INTERFACE FRAMEWORK
 M:	Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
 L:	netdev@vger.kernel.org
@@ -20115,7 +20118,9 @@
 
 PAGE CACHE
 M:	Matthew Wilcox (Oracle) <willy@infradead.org>
+R:	Jan Kara <jack@suse.cz>
 L:	linux-fsdevel@vger.kernel.org
+L:	linux-mm@kvack.org
 S:	Supported
 T:	git git://git.infradead.org/users/willy/pagecache.git
 F:	Documentation/filesystems/locking.rst
@@ -20881,7 +20886,7 @@
 R:	John Garry <john.g.garry@oracle.com>
 R:	Will Deacon <will@kernel.org>
 R:	James Clark <james.clark@linaro.org>
-R:	Mike Leach <mike.leach@linaro.org>
+R:	Mike Leach <mike.leach@arm.com>
 R:	Leo Yan <leo.yan@linux.dev>
 L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:	Supported
@@ -23000,8 +23005,12 @@
 L:	linux-riscv@lists.infradead.org
 S:	Maintained
 T:	git https://github.com/tenstorrent/linux.git
+F:	Documentation/devicetree/bindings/clock/tenstorrent,atlantis-prcm-rcpu.yaml
 F:	Documentation/devicetree/bindings/riscv/tenstorrent.yaml
 F:	arch/riscv/boot/dts/tenstorrent/
+F:	drivers/clk/tenstorrent/
+F:	drivers/reset/reset-tenstorrent-atlantis.c
+F:	include/dt-bindings/clock/tenstorrent,atlantis-prcm-rcpu.h
 
 RISC-V THEAD SoC SUPPORT
 M:	Drew Fustini <fustini@kernel.org>
@@ -23235,14 +23244,6 @@
 F:	include/linux/mfd/rohm-generic.h
 F:	include/linux/mfd/rohm-shared.h
 
-ROSE NETWORK LAYER
-L:	linux-hams@vger.kernel.org
-S:	Orphan
-W:	https://linux-ax25.in-berlin.de
-F:	include/net/rose.h
-F:	include/uapi/linux/rose.h
-F:	net/rose/
-
 ROTATION DRIVER FOR ALLWINNER A83T
 M:	Jernej Skrabec <jernej.skrabec@gmail.com>
 L:	linux-media@vger.kernel.org
@@ -24613,7 +24614,7 @@
 L:	samba-technical@lists.samba.org (moderated for non-subscribers)
 S:	Maintained
 F:	fs/smb/client/smbdirect.*
-F:	fs/smb/common/smbdirect/
+F:	fs/smb/smbdirect/
 F:	fs/smb/server/transport_rdma.*
 
 SMC91x ETHERNET DRIVER
@@ -24681,8 +24682,8 @@
 F:	drivers/net/ethernet/socionext/netsec.c
 
 SOCIONEXT (SNI) Synquacer SPI DRIVER
-M:	Masahisa Kojima <masahisa.kojima@linaro.org>
-M:	Jassi Brar <jaswinder.singh@linaro.org>
+M:	Masahisa Kojima <kojima.masahisa@socionext.com>
+M:	Jassi Brar <jassisinghbrar@gmail.com>
 L:	linux-spi@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/spi/socionext,synquacer-spi.yaml
@@ -24729,6 +24730,7 @@
 S:	Supported
 F:	drivers/infiniband/sw/rxe/
 F:	include/uapi/rdma/rdma_user_rxe.h
+F:	tools/testing/selftests/rdma/rxe*
 
 SOFTLOGIC 6x10 MPEG CODEC
 M:	Bluecherry Maintainers <maintainers@bluecherrydvr.com>
@@ -25319,6 +25321,13 @@
 F:	Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
 F:	drivers/iio/proximity/vl53l0x-i2c.c
 
+ST VL53L1X ToF RANGER(I2C) IIO DRIVER
+M:	Siratul Islam <email@sirat.me>
+L:	linux-iio@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/iio/proximity/st,vl53l0x.yaml
+F:	drivers/iio/proximity/vl53l1x-i2c.c
+
 STABLE BRANCH
 M:	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 M:	Sasha Levin <sashal@kernel.org>
@@ -25475,10 +25484,11 @@
 F:	drivers/reset/starfive/reset-starfive-jh71*
 F:	include/dt-bindings/reset/starfive?jh71*.h
 
-STARFIVE JH71X0 USB DRIVERS
+STARFIVE USB DRIVERS
 M:	Minda Chen <minda.chen@starfivetech.com>
 S:	Maintained
 F:	Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml
+F:	Documentation/devicetree/bindings/usb/starfive,jhb100-dwc3.yaml
 F:	drivers/usb/cdns3/cdns3-starfive.c
 
 STARFIVE JH71XX PMU CONTROLLER DRIVER
@@ -26525,7 +26535,7 @@
 F:	include/uapi/linux/thp7312.h
 
 THUNDERBOLT DMA TRAFFIC TEST DRIVER
-M:	Isaac Hazan <isaac.hazan@intel.com>
+M:	Mika Westerberg <westeri@kernel.org>
 L:	linux-usb@vger.kernel.org
 S:	Maintained
 F:	drivers/thunderbolt/dma_test.c
@@ -29295,13 +29305,6 @@
 F:	lib/xz/
 F:	scripts/xz_wrap.sh
 
-YAM DRIVER FOR AX.25
-M:	Jean-Paul Roubelat <jpr@f6fbb.org>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-F:	drivers/net/hamradio/yam*
-F:	include/linux/yam.h
-
 YAMA SECURITY MODULE
 M:	Kees Cook <kees@kernel.org>
 S:	Supported
@@ -29323,16 +29326,6 @@
 F:	Documentation/input/devices/yealink.rst
 F:	drivers/input/misc/yealink.*
 
-Z8530 DRIVER FOR AX.25
-M:	Joerg Reuter <jreuter@yaina.de>
-L:	linux-hams@vger.kernel.org
-S:	Maintained
-W:	http://yaina.de/jreuter/
-W:	http://www.qsl.net/dl1bke/
-F:	Documentation/networking/device_drivers/hamradio/z8530drv.rst
-F:	drivers/net/hamradio/*scc.c
-F:	drivers/net/hamradio/z8530.h
-
 ZD1211RW WIRELESS DRIVER
 L:	linux-wireless@vger.kernel.org
 S:	Orphan
diff --git a/arch/Kconfig b/arch/Kconfig
index fa1d4bc..e868800 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1127,6 +1127,13 @@
 	  For architectures like powerpc/32 which have constraints on module
 	  allocation and need to allocate module data outside of module area.
 
+config ARCH_WANTS_MODULES_TEXT_SECTIONS
+	bool
+	help
+	  For architectures like 32-bit parisc which require that functions in
+	  modules have to keep code in own text sections (-ffunction-sections)
+	  and to avoid merging all text into one big text section,
+
 config ARCH_WANTS_EXECMEM_LATE
 	bool
 	help
diff --git a/arch/alpha/configs/defconfig b/arch/alpha/configs/defconfig
index 3280bd9..29748bb 100644
--- a/arch/alpha/configs/defconfig
+++ b/arch/alpha/configs/defconfig
@@ -45,7 +45,6 @@
 CONFIG_DE2104X=m
 CONFIG_TULIP=y
 CONFIG_TULIP_MMIO=y
-CONFIG_YELLOWFIN=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_RTC_CLASS=y
diff --git a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
index d170c71..e85693f 100644
--- a/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
+++ b/arch/arm/boot/dts/broadcom/bcm4709-netgear-r8000.dts
@@ -139,7 +139,6 @@ &pcie_bridge1 {
 	pcie@0,0 {
 		device_type = "pci";
 		reg = <0x0000 0 0 0 0>;
-		bus-range = <0x01 0xff>;
 
 		#address-cells = <3>;
 		#size-cells = <2>;
diff --git a/arch/arm/boot/dts/marvell/armada-380.dtsi b/arch/arm/boot/dts/marvell/armada-380.dtsi
deleted file mode 100644
index e94f22b..0000000
--- a/arch/arm/boot/dts/marvell/armada-380.dtsi
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Device Tree Include file for Marvell Armada 380 SoC.
- *
- * Copyright (C) 2014 Marvell
- *
- * Lior Amsalem <alior@marvell.com>
- * Gregory CLEMENT <gregory.clement@free-electrons.com>
- * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
- */
-
-#include "armada-38x.dtsi"
-
-/ {
-	model = "Marvell Armada 380 family SoC";
-	compatible = "marvell,armada380";
-
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		enable-method = "marvell,armada-380-smp";
-
-		cpu@0 {
-			device_type = "cpu";
-			compatible = "arm,cortex-a9";
-			reg = <0>;
-		};
-	};
-
-	soc {
-		internal-regs {
-			pinctrl@18000 {
-				compatible = "marvell,mv88f6810-pinctrl";
-			};
-		};
-
-		pcie {
-			compatible = "marvell,armada-370-pcie";
-			status = "disabled";
-			device_type = "pci";
-
-			#address-cells = <3>;
-			#size-cells = <2>;
-
-			msi-parent = <&mpic>;
-			bus-range = <0x00 0xff>;
-
-			ranges =
-			       <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000
-				0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000
-				0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000
-				0x82000000 0 0x48000 MBUS_ID(0xf0, 0x01) 0x48000 0 0x00002000
-				0x82000000 0x1 0     MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 0 MEM */
-				0x81000000 0x1 0     MBUS_ID(0x08, 0xe0) 0 1 0 /* Port 0 IO  */
-				0x82000000 0x2 0     MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 1 MEM */
-				0x81000000 0x2 0     MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 1 IO  */
-				0x82000000 0x3 0     MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 2 MEM */
-				0x81000000 0x3 0     MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 2 IO  */>;
-
-			/* x1 port */
-			pcie@1,0 {
-				device_type = "pci";
-				assigned-addresses = <0x82000800 0 0x80000 0 0x2000>;
-				reg = <0x0800 0 0 0 0>;
-				#address-cells = <3>;
-				#size-cells = <2>;
-				interrupt-names = "intx";
-				interrupts-extended = <&gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-				#interrupt-cells = <1>;
-				ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0
-					  0x81000000 0 0 0x81000000 0x1 0 1 0>;
-				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 7>;
-				interrupt-map = <0 0 0 1 &pcie1_intc 0>,
-						<0 0 0 2 &pcie1_intc 1>,
-						<0 0 0 3 &pcie1_intc 2>,
-						<0 0 0 4 &pcie1_intc 3>;
-				marvell,pcie-port = <0>;
-				marvell,pcie-lane = <0>;
-				clocks = <&gateclk 8>;
-				status = "disabled";
-
-				pcie1_intc: interrupt-controller {
-					interrupt-controller;
-					#interrupt-cells = <1>;
-				};
-			};
-
-			/* x1 port */
-			pcie@2,0 {
-				device_type = "pci";
-				assigned-addresses = <0x82001000 0 0x40000 0 0x2000>;
-				reg = <0x1000 0 0 0 0>;
-				#address-cells = <3>;
-				#size-cells = <2>;
-				interrupt-names = "intx";
-				interrupts-extended = <&gic GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-				#interrupt-cells = <1>;
-				ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0
-					  0x81000000 0 0 0x81000000 0x2 0 1 0>;
-				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 7>;
-				interrupt-map = <0 0 0 1 &pcie2_intc 0>,
-						<0 0 0 2 &pcie2_intc 1>,
-						<0 0 0 3 &pcie2_intc 2>,
-						<0 0 0 4 &pcie2_intc 3>;
-				marvell,pcie-port = <1>;
-				marvell,pcie-lane = <0>;
-				clocks = <&gateclk 5>;
-				status = "disabled";
-
-				pcie2_intc: interrupt-controller {
-					interrupt-controller;
-					#interrupt-cells = <1>;
-				};
-			};
-
-			/* x1 port */
-			pcie@3,0 {
-				device_type = "pci";
-				assigned-addresses = <0x82001800 0 0x44000 0 0x2000>;
-				reg = <0x1800 0 0 0 0>;
-				#address-cells = <3>;
-				#size-cells = <2>;
-				interrupt-names = "intx";
-				interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
-				#interrupt-cells = <1>;
-				ranges = <0x82000000 0 0 0x82000000 0x3 0 1 0
-					  0x81000000 0 0 0x81000000 0x3 0 1 0>;
-				bus-range = <0x00 0xff>;
-				interrupt-map-mask = <0 0 0 7>;
-				interrupt-map = <0 0 0 1 &pcie3_intc 0>,
-						<0 0 0 2 &pcie3_intc 1>,
-						<0 0 0 3 &pcie3_intc 2>,
-						<0 0 0 4 &pcie3_intc 3>;
-				marvell,pcie-port = <2>;
-				marvell,pcie-lane = <0>;
-				clocks = <&gateclk 6>;
-				status = "disabled";
-
-				pcie3_intc: interrupt-controller {
-					interrupt-controller;
-					#interrupt-cells = <1>;
-				};
-			};
-		};
-	};
-};
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 81199dd..01d7258 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -52,9 +52,6 @@
 CONFIG_IP_NF_ARPTABLES=m
 CONFIG_IP_NF_ARPFILTER=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
@@ -108,7 +105,6 @@
 CONFIG_PATA_IXP4XX_CF=y
 CONFIG_NETDEVICES=y
 CONFIG_DUMMY=y
-CONFIG_ATM_TCP=m
 CONFIG_IXP4XX_ETH=y
 CONFIG_WAN=y
 CONFIG_HDLC=y
diff --git a/arch/arm/configs/neponset_defconfig b/arch/arm/configs/neponset_defconfig
index 4d72000..8a5dcca 100644
--- a/arch/arm/configs/neponset_defconfig
+++ b/arch/arm/configs/neponset_defconfig
@@ -40,7 +40,6 @@
 CONFIG_NETDEVICES=y
 CONFIG_NET_VENDOR_SMC=y
 CONFIG_PCMCIA_PCNET=y
-CONFIG_SMC9194=y
 CONFIG_SMC91X=y
 CONFIG_NET_PCMCIA=y
 # CONFIG_INPUT_MOUSE is not set
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index ba6ddaf..2fe25f5 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -37,7 +37,6 @@
 CONFIG_CFG80211_DEBUGFS=y
 CONFIG_MAC80211=y
 CONFIG_MAC80211_LEDS=y
-CONFIG_CAIF=y
 CONFIG_NFC=m
 CONFIG_NFC_HCI=m
 CONFIG_NFC_SHDLC=y
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index a0af483..fe60738 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1142,6 +1142,18 @@
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_4193714
+	bool "C1-Pro: 4193714: SME DVMSync early acknowledgement"
+	depends on ARM64_SME
+	default y
+	help
+	  Enable workaround for C1-Pro acknowledging the DVMSync before
+	  the SME memory accesses are complete. This will cause TLB
+	  maintenance for processes using SME to also issue an IPI to
+	  the affected CPUs.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi
index 8ef63193..ab3acef 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi
@@ -53,10 +53,10 @@ pwrc: power-controller {
 
 	timer {
 		compatible = "arm,armv8-timer";
-		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
-			     <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+		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>;
 	};
 
 	psci {
@@ -84,7 +84,7 @@ gic: interrupt-controller@ff200000 {
 			interrupt-controller;
 			reg = <0x0 0xff200000 0 0x10000>,
 			      <0x0 0xff240000 0 0x80000>;
-			interrupts = <GIC_PPI 9 0xf04>;
+			interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 		};
 
 		apb: bus@fe000000 {
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
index fffdab9..f4c9530 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -8,7 +8,7 @@
 #include "amlogic-t7.dtsi"
 
 / {
-	model = "Khadas vim4";
+	model = "Khadas VIM4";
 	compatible = "khadas,vim4", "amlogic,a311d2", "amlogic,t7";
 
 	aliases {
@@ -17,7 +17,9 @@ aliases {
 
 	memory@0 {
 		device_type = "memory";
-		reg = <0x0 0x0 0x2 0x0>; /* 8 GB */
+		reg = <0x0 0x0 0x0 0xE0000000
+			0x1 0x0 0x0 0xE0000000
+			0x2 0x0 0x0 0x40000000>; /* 8 GB */
 	};
 
 	reserved-memory {
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
index 6510068..d523cbc 100644
--- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
+++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -213,7 +213,9 @@ gic: interrupt-controller@fff01000 {
 			#address-cells = <0>;
 			interrupt-controller;
 			reg = <0x0 0xfff01000 0 0x1000>,
-			      <0x0 0xfff02000 0 0x0100>;
+			      <0x0 0xfff02000 0 0x2000>,
+			      <0x0 0xfff04000 0 0x2000>,
+			      <0x0 0xfff06000 0 0x2000>;
 			interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
 		};
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index cc72491..f1f53fd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -72,6 +72,12 @@ cpu0: cpu@0 {
 			compatible = "arm,cortex-a53";
 			reg = <0x0 0x0>;
 			enable-method = "psci";
+			d-cache-line-size = <32>;
+			d-cache-size = <0x8000>;
+			d-cache-sets = <32>;
+			i-cache-line-size = <32>;
+			i-cache-size = <0x8000>;
+			i-cache-sets = <32>;
 			next-level-cache = <&l2>;
 			clocks = <&scpi_dvfs 0>;
 			dynamic-power-coefficient = <140>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
index 7dffeb5..701de57 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-p230.dts
@@ -84,7 +84,8 @@ external_phy: ethernet-phy@0 {
 		reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
 
 		interrupt-parent = <&gpio_intc>;
-		interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+		/* MAC_INTR on GPIOZ_15 */
+		interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
 		eee-broken-1000t;
 	};
 };
diff --git a/arch/arm64/boot/dts/apple/spi1-nvram.dtsi b/arch/arm64/boot/dts/apple/spi1-nvram.dtsi
index 9740fbf..d2720b3 100644
--- a/arch/arm64/boot/dts/apple/spi1-nvram.dtsi
+++ b/arch/arm64/boot/dts/apple/spi1-nvram.dtsi
@@ -2,7 +2,7 @@
 //
 // Devicetree include for common spi-nor nvram flash.
 //
-// Apple uses a consistent configiguration for the nvram on all known M1* and
+// Apple uses a consistent configuration for the nvram on all known M1* and
 // M2* devices.
 //
 // Copyright The Asahi Linux Contributors
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
index 67d22d3..507d182 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-emtop-som.dtsi
@@ -60,7 +60,7 @@ pmic@25 {
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_pmic>;
 		interrupt-parent = <&gpio1>;
-		interrupts = <3 IRQ_TYPE_EDGE_RISING>;
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
 
 		regulators {
 			buck1: BUCK1 {
@@ -194,7 +194,7 @@ MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA				0x400001c3
 
 	pinctrl_pmic: emtop-pmic-grp {
 		fsl,pins = <
-			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3			0x41
+			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3			0x141
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
index 29b298a..1b5ba3c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mm-tqma8mqml.dtsi
@@ -292,7 +292,7 @@ pinctrl_i2c1_gpio: i2c1gpiogrp {
 	};
 
 	pinctrl_pmic: pmicgrp {
-		fsl,pins = <MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x94>;
+		fsl,pins = <MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8		0x1d4>;
 	};
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
index 31a3ca1..48a6879 100644
--- a/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mn-tqma8mqnl.dtsi
@@ -283,7 +283,7 @@ pinctrl_i2c1_gpio: i2c1gpiogrp {
 	};
 
 	pinctrl_pmic: pmicgrp {
-		fsl,pins = <MX8MN_IOMUXC_GPIO1_IO08_GPIO1_IO8	0x84>;
+		fsl,pins = <MX8MN_IOMUXC_GPIO1_IO08_GPIO1_IO8	0x1c4>;
 	};
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-aristainetos3a-som-v1.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-aristainetos3a-som-v1.dtsi
index f654d86..e7666e5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-aristainetos3a-som-v1.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-aristainetos3a-som-v1.dtsi
@@ -903,7 +903,7 @@ MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20	0x41
 
 	pinctrl_pmic: aristainetos3-pmic-grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
index 7e46537..cb28cf1 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -1001,7 +1001,7 @@ MX8MP_IOMUXC_SAI3_RXFS__AUDIOMIX_PDM_BIT_STREAM00	0x0
 	pinctrl_pmic: pmic-grp {
 		fsl,pins = <
 			/* PMIC_nINT */
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x40000090
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
index 9422bee..201cf7f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-model-a.dts
@@ -440,7 +440,7 @@ MX8MP_IOMUXC_SAI5_RXC__I2C6_SDA					0x400001c3
 
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03				0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03				0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
index 04619a7..1471ff3 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a-bmb-08.dts
@@ -499,7 +499,7 @@ MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03		0x140
 
 	pinctrl_pmic: pmicgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a.dtsi
index 91094c2..b31e8fe 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-debix-som-a.dtsi
@@ -241,7 +241,7 @@ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA			0x400001c3
 
 	pinctrl_pmic: pmicgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
index f8303b7..0a6a606 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-dhcom-som.dtsi
@@ -989,7 +989,7 @@ MX8MP_IOMUXC_SAI5_RXC__GPIO3_IO20		0x22
 	pinctrl_pmic: dhcom-pmic-grp {
 		fsl,pins = <
 			/* PMIC_nINT */
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x40000090
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-edm-g.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-edm-g.dtsi
index 3f1e083..91b87a7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-edm-g.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-edm-g.dtsi
@@ -563,7 +563,7 @@ MX8MP_IOMUXC_GPIO1_IO01__GPIO1_IO01	0x41 /* PCIE RST */
 
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03	0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi
index a631982..69558ff 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi
@@ -132,7 +132,7 @@ MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c3
 
 	pinctrl_pmic: pmicgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01	  0x41
+			MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01	0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts b/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
index 4a4f7c1..9dedb9f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-navqp.dts
@@ -356,7 +356,7 @@ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA					0x400001c3
 
 	pinctrl_pmic: pmicgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03				0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03				0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-nitrogen-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-nitrogen-som.dtsi
index f658309..8465b36 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-nitrogen-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-nitrogen-som.dtsi
@@ -296,7 +296,7 @@ MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA		0x400001c3
 
 	pinctrl_pmic: pmicirqgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00	0x41
+			MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00	0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
index 3cdb0bc..c3f7daa 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
@@ -174,7 +174,7 @@ pmic: pmic@25 {
 		pinctrl-0 = <&pmic_pins>;
 		pinctrl-names = "default";
 		interrupt-parent = <&gpio1>;
-		interrupts = <3 GPIO_ACTIVE_LOW>;
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
 		nxp,i2c-lt-enable;
 
 		regulators {
@@ -417,7 +417,7 @@ MX8MP_IOMUXC_SAI1_RXD1__GPIO4_IO03		0x160
 
 	pmic_pins: pinctrl-pmic-grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x41
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-ultra-mach-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-ultra-mach-sbc.dts
index 9ecec1a4..3e6f9c8 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-ultra-mach-sbc.dts
+++ b/arch/arm64/boot/dts/freescale/imx8mp-ultra-mach-sbc.dts
@@ -275,7 +275,7 @@ pmic@25 {
 		reg = <0x25>;
 		pinctrl-0 = <&pinctrl_pmic>;
 		interrupt-parent = <&gpio1>;
-		interrupts = <3 GPIO_ACTIVE_LOW>;
+		interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
 
 		/*
 		 * i.MX 8M Plus Data Sheet for Consumer Products
@@ -739,7 +739,7 @@ MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07		0x40	/* NFC_INT */
 
 	pinctrl_pmic: pmic-grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x40	/* #PMIC_INT */
+			MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03		0x1c0	/* #PMIC_INT */
 		>;
 	};
 
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-atlas-v5.dts b/arch/arm64/boot/dts/marvell/armada-3720-atlas-v5.dts
index 070d10a..a313d56 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-atlas-v5.dts
+++ b/arch/arm64/boot/dts/marvell/armada-3720-atlas-v5.dts
@@ -82,7 +82,6 @@ &sdhci0 {
 	mmc-ddr-1_8v;
 	mmc-hs400-1_8v;
 	sd-uhs-sdr104;
-	marvell,xenon-emmc;
 	marvell,xenon-tun-count = <9>;
 	marvell,pad-type = "fixed-1-8v";
 	vqmmc-supply = <&vsdc_reg>;
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
index fed2dce..37e16fb 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-espressobin.dtsi
@@ -78,7 +78,6 @@ &sdhci0 {
 	bus-width = <8>;
 	mmc-ddr-1_8v;
 	mmc-hs400-1_8v;
-	marvell,xenon-emmc;
 	marvell,xenon-tun-count = <9>;
 	marvell,pad-type = "fixed-1-8v";
 
diff --git a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
index 2428208..12deacb 100644
--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi
@@ -15,6 +15,11 @@
 #include "armada-372x.dtsi"
 
 / {
+	aliases {
+		ethernet0 = &eth0;
+		ethernet1 = &eth1;
+	};
+
 	chosen {
 		stdout-path = "serial0:115200n8";
 	};
@@ -156,7 +161,7 @@ &eth1 {
 &usb3 {
 	status = "okay";
 	phys = <&usb2_utmi_otg_phy>;
-	phy-names = "usb2-utmi-otg-phy";
+	phy-names = "usb2-phy";
 };
 
 &uart0 {
diff --git a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
index 87f9367..360fc24 100644
--- a/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-37xx.dtsi
@@ -369,11 +369,10 @@ usb3: usb@58000 {
 				compatible = "marvell,armada3700-xhci",
 				"generic-xhci";
 				reg = <0x58000 0x4000>;
-				marvell,usb-misc-reg = <&usb32_syscon>;
 				interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&sb_periph_clk 12>;
-				phys = <&comphy0 0>, <&usb2_utmi_otg_phy>;
-				phy-names = "usb3-phy", "usb2-utmi-otg-phy";
+				phys = <&usb2_utmi_otg_phy>, <&comphy0 0>;
+				phy-names = "usb2-phy", "usb3-phy";
 				status = "disabled";
 			};
 
@@ -393,10 +392,9 @@ usb32_syscon: system-controller@5d800 {
 			usb2: usb@5e000 {
 				compatible = "marvell,armada-3700-ehci";
 				reg = <0x5e000 0x1000>;
-				marvell,usb-misc-reg = <&usb2_syscon>;
 				interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
 				phys = <&usb2_utmi_host_phy>;
-				phy-names = "usb2-utmi-host-phy";
+				phy-names = "usb";
 				status = "disabled";
 			};
 
@@ -534,7 +532,6 @@ firmware {
 		armada-3700-rwtm {
 			compatible = "marvell,armada-3700-rwtm-firmware";
 			mboxes = <&rwtm 0>;
-			status = "okay";
 		};
 	};
 };
diff --git a/arch/arm64/boot/dts/marvell/armada-7020-comexpress.dtsi b/arch/arm64/boot/dts/marvell/armada-7020-comexpress.dtsi
index 2b5ec4a..0cfcf5f 100644
--- a/arch/arm64/boot/dts/marvell/armada-7020-comexpress.dtsi
+++ b/arch/arm64/boot/dts/marvell/armada-7020-comexpress.dtsi
@@ -70,7 +70,7 @@ &cp0_eth0 {
 
 &cp0_eth1 {
 	status = "okay";
-	phy = <&phy0>;
+	phy-handle = <&phy0>;
 	phy-mode = "rgmii-id";
 };
 
diff --git a/arch/arm64/boot/dts/marvell/armada-8020.dtsi b/arch/arm64/boot/dts/marvell/armada-8020.dtsi
deleted file mode 100644
index b6fc188..0000000
--- a/arch/arm64/boot/dts/marvell/armada-8020.dtsi
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2016 Marvell Technology Group Ltd.
- *
- * Device Tree file for the Armada 8020 SoC, made of an AP806 Dual and
- * two CP110.
- */
-
-#include "armada-ap806-dual.dtsi"
-#include "armada-80x0.dtsi"
-
-/* The RTC requires external oscillator. But on Aramda 80x0, the RTC clock
- * in CP master is not connected (by package) to the oscillator. So
- * disable it. However, the RTC clock in CP slave is connected to the
- * oscillator so this one is let enabled.
- */
-
-&cp0_rtc {
-	status = "disabled";
-};
diff --git a/arch/arm64/boot/dts/marvell/cn9130-db-comexpress.dtsi b/arch/arm64/boot/dts/marvell/cn9130-db-comexpress.dtsi
deleted file mode 100644
index 028496e..0000000
--- a/arch/arm64/boot/dts/marvell/cn9130-db-comexpress.dtsi
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2023 Marvell International Ltd.
- *
- * Device tree for the CN9130-DB Com Express CPU module board.
- */
-
-#include "cn9130-db.dtsi"
-
-/ {
-	model = "Marvell Armada CN9130-DB COM EXPRESS type 7 CPU module board";
-	compatible = "marvell,cn9130-cpu-module", "marvell,cn9130",
-		     "marvell,armada-ap807-quad", "marvell,armada-ap807";
-
-};
-
-&ap0_reg_sd_vccq {
-	regulator-max-microvolt = <1800000>;
-	states = <1800000 0x1 1800000 0x0>;
-	/delete-property/ gpios;
-};
-
-&cp0_reg_usb3_vbus0 {
-	/delete-property/ gpio;
-};
-
-&cp0_reg_usb3_vbus1 {
-	/delete-property/ gpio;
-};
-
-&cp0_reg_sd_vcc {
-	status = "disabled";
-};
-
-&cp0_reg_sd_vccq {
-	status = "disabled";
-};
-
-&cp0_sdhci0 {
-	status = "disabled";
-};
-
-&cp0_eth0 {
-	status = "disabled";
-};
-
-&cp0_eth1 {
-	status = "okay";
-	phy = <&phy0>;
-	phy-mode = "rgmii-id";
-};
-
-&cp0_eth2 {
-	status = "disabled";
-};
-
-&cp0_mdio {
-	status = "okay";
-	pinctrl-0 = <&cp0_ge_mdio_pins>;
-	phy0: ethernet-phy@0 {
-		status = "okay";
-	};
-};
-
-&cp0_syscon0 {
-	cp0_pinctrl: pinctrl {
-		compatible = "marvell,cp115-standalone-pinctrl";
-
-		cp0_ge_mdio_pins: ge-mdio-pins {
-			marvell,pins = "mpp40", "mpp41";
-			marvell,function = "ge";
-		};
-	};
-};
-
-&cp0_sdhci0 {
-	status = "disabled";
-};
-
-&cp0_spi1 {
-	status = "okay";
-};
-
-&cp0_usb3_0 {
-	status = "okay";
-	usb-phy = <&cp0_usb3_0_phy0>;
-	phy-names = "usb";
-	/delete-property/ phys;
-};
-
-&cp0_usb3_1 {
-	status = "okay";
-	usb-phy = <&cp0_usb3_0_phy1>;
-	phy-names = "usb";
-	/delete-property/ phys;
-};
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index d2ff8f6..3144179 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -17,4 +17,5 @@
 generic-y += user.h
 
 generated-y += cpucap-defs.h
+generated-y += kernel-hwcap.h
 generated-y += sysreg-defs.h
diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index 6e3da333..d0d3cdd 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -64,6 +64,8 @@ cpucap_is_possible(const unsigned int cap)
 		return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
 	case ARM64_WORKAROUND_SPECULATIVE_SSBS:
 		return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
+	case ARM64_WORKAROUND_4193714:
+		return IS_ENABLED(CONFIG_ARM64_ERRATUM_4193714);
 	case ARM64_MPAM:
 		/*
 		 * KVM MPAM support doesn't rely on the host kernel supporting MPAM.
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 08860d4..7b518e8 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -98,6 +98,7 @@
 #define ARM_CPU_PART_CORTEX_A725	0xD87
 #define ARM_CPU_PART_CORTEX_A720AE	0xD89
 #define ARM_CPU_PART_NEOVERSE_N3	0xD8E
+#define ARM_CPU_PART_C1_PRO		0xD8B
 
 #define APM_CPU_PART_XGENE		0x000
 #define APM_CPU_VAR_POTENZA		0x00
@@ -189,6 +190,7 @@
 #define MIDR_CORTEX_A725 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A725)
 #define MIDR_CORTEX_A720AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A720AE)
 #define MIDR_NEOVERSE_N3 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N3)
+#define MIDR_C1_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_C1_PRO)
 #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)
diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
index 1d2e335..d9d00b4 100644
--- a/arch/arm64/include/asm/fpsimd.h
+++ b/arch/arm64/include/asm/fpsimd.h
@@ -428,6 +428,24 @@ static inline size_t sme_state_size(struct task_struct const *task)
 	return __sme_state_size(task_get_sme_vl(task));
 }
 
+void sme_enable_dvmsync(void);
+void sme_set_active(void);
+void sme_clear_active(void);
+
+static inline void sme_enter_from_user_mode(void)
+{
+	if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714) &&
+	    test_thread_flag(TIF_SME))
+		sme_clear_active();
+}
+
+static inline void sme_exit_to_user_mode(void)
+{
+	if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714) &&
+	    test_thread_flag(TIF_SME))
+		sme_set_active();
+}
+
 #else
 
 static inline void sme_user_disable(void) { BUILD_BUG(); }
@@ -456,6 +474,9 @@ static inline size_t sme_state_size(struct task_struct const *task)
 	return 0;
 }
 
+static inline void sme_enter_from_user_mode(void) { }
+static inline void sme_exit_to_user_mode(void) { }
+
 #endif /* ! CONFIG_ARM64_SME */
 
 /* For use by EFI runtime services calls only */
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 9029b81..4dfa42b 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -1276,17 +1276,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
 #endif
 
 #ifdef CONFIG_PAGE_TABLE_CHECK
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return pte_valid(pte) && (pte_user(pte) || pte_user_exec(pte));
 }
 
-static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
+static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
 {
 	return pmd_valid(pmd) && !pmd_table(pmd) && (pmd_user(pmd) || pmd_user_exec(pmd));
 }
 
-static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
+static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
 {
 	return pud_valid(pud) && !pud_table(pud) && (pud_user(pud) || pud_user_exec(pud));
 }
diff --git a/arch/arm64/include/asm/tlbbatch.h b/arch/arm64/include/asm/tlbbatch.h
index fedb0b8..6297631 100644
--- a/arch/arm64/include/asm/tlbbatch.h
+++ b/arch/arm64/include/asm/tlbbatch.h
@@ -2,11 +2,17 @@
 #ifndef _ARCH_ARM64_TLBBATCH_H
 #define _ARCH_ARM64_TLBBATCH_H
 
+#include <linux/cpumask.h>
+
 struct arch_tlbflush_unmap_batch {
+#ifdef CONFIG_ARM64_ERRATUM_4193714
 	/*
-	 * For arm64, HW can do tlb shootdown, so we don't
-	 * need to record cpumask for sending IPI
+	 * Track CPUs that need SME DVMSync on completion of this batch.
+	 * Otherwise, the arm64 HW can do tlb shootdown, so we don't need to
+	 * record cpumask for sending IPI
 	 */
+	cpumask_var_t cpumask;
+#endif
 };
 
 #endif /* _ARCH_ARM64_TLBBATCH_H */
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 47fa4d3..c0bf5b3 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -80,6 +80,71 @@ static inline unsigned long get_trans_granule(void)
 	}
 }
 
+#ifdef CONFIG_ARM64_ERRATUM_4193714
+
+void sme_do_dvmsync(const struct cpumask *mask);
+
+static inline void sme_dvmsync(struct mm_struct *mm)
+{
+	if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
+		return;
+
+	sme_do_dvmsync(mm_cpumask(mm));
+}
+
+static inline void sme_dvmsync_add_pending(struct arch_tlbflush_unmap_batch *batch,
+					   struct mm_struct *mm)
+{
+	if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
+		return;
+
+	/*
+	 * Order the mm_cpumask() read after the hardware DVMSync.
+	 */
+	dsb(ish);
+	if (cpumask_empty(mm_cpumask(mm)))
+		return;
+
+	/*
+	 * Allocate the batch cpumask on first use. Fall back to an immediate
+	 * IPI for this mm in case of failure.
+	 */
+	if (!cpumask_available(batch->cpumask) &&
+	    !zalloc_cpumask_var(&batch->cpumask, GFP_ATOMIC)) {
+		sme_do_dvmsync(mm_cpumask(mm));
+		return;
+	}
+
+	cpumask_or(batch->cpumask, batch->cpumask, mm_cpumask(mm));
+}
+
+static inline void sme_dvmsync_batch(struct arch_tlbflush_unmap_batch *batch)
+{
+	if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
+		return;
+
+	if (!cpumask_available(batch->cpumask))
+		return;
+
+	sme_do_dvmsync(batch->cpumask);
+	cpumask_clear(batch->cpumask);
+}
+
+#else
+
+static inline void sme_dvmsync(struct mm_struct *mm)
+{
+}
+static inline void sme_dvmsync_add_pending(struct arch_tlbflush_unmap_batch *batch,
+					   struct mm_struct *mm)
+{
+}
+static inline void sme_dvmsync_batch(struct arch_tlbflush_unmap_batch *batch)
+{
+}
+
+#endif /* CONFIG_ARM64_ERRATUM_4193714 */
+
 /*
  * Level-based TLBI operations.
  *
@@ -213,7 +278,21 @@ do {										\
  * Complete broadcast TLB maintenance issued by the host which invalidates
  * stage 1 information in the host's own translation regime.
  */
-static inline void __tlbi_sync_s1ish(void)
+static inline void __tlbi_sync_s1ish(struct mm_struct *mm)
+{
+	dsb(ish);
+	__repeat_tlbi_sync(vale1is, 0);
+	sme_dvmsync(mm);
+}
+
+static inline void __tlbi_sync_s1ish_batch(struct arch_tlbflush_unmap_batch *batch)
+{
+	dsb(ish);
+	__repeat_tlbi_sync(vale1is, 0);
+	sme_dvmsync_batch(batch);
+}
+
+static inline void __tlbi_sync_s1ish_kernel(void)
 {
 	dsb(ish);
 	__repeat_tlbi_sync(vale1is, 0);
@@ -322,7 +401,7 @@ static inline void flush_tlb_all(void)
 {
 	dsb(ishst);
 	__tlbi(vmalle1is);
-	__tlbi_sync_s1ish();
+	__tlbi_sync_s1ish_kernel();
 	isb();
 }
 
@@ -334,7 +413,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm)
 	asid = __TLBI_VADDR(0, ASID(mm));
 	__tlbi(aside1is, asid);
 	__tlbi_user(aside1is, asid);
-	__tlbi_sync_s1ish();
+	__tlbi_sync_s1ish(mm);
 	mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL);
 }
 
@@ -355,7 +434,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm)
  */
 static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
 {
-	__tlbi_sync_s1ish();
+	__tlbi_sync_s1ish_batch(batch);
 }
 
 /*
@@ -557,7 +636,7 @@ static __always_inline void __do_flush_tlb_range(struct vm_area_struct *vma,
 
 	if (!(flags & TLBF_NOSYNC)) {
 		if (!(flags & TLBF_NOBROADCAST))
-			__tlbi_sync_s1ish();
+			__tlbi_sync_s1ish(mm);
 		else
 			dsb(nsh);
 	}
@@ -618,7 +697,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end
 	dsb(ishst);
 	__flush_s1_tlb_range_op(vaale1is, start, pages, stride, 0,
 				TLBI_TTL_UNKNOWN);
-	__tlbi_sync_s1ish();
+	__tlbi_sync_s1ish_kernel();
 	isb();
 }
 
@@ -632,7 +711,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
 
 	dsb(ishst);
 	__tlbi(vaae1is, addr);
-	__tlbi_sync_s1ish();
+	__tlbi_sync_s1ish_kernel();
 	isb();
 }
 
@@ -643,6 +722,7 @@ static inline void arch_tlbbatch_add_pending(struct arch_tlbflush_unmap_batch *b
 
 	__flush_tlb_range(&vma, start, end, PAGE_SIZE, 3,
 			  TLBF_NOWALKCACHE | TLBF_NOSYNC);
+	sme_dvmsync_add_pending(batch, mm);
 }
 
 static inline bool __pte_flags_need_flush(ptdesc_t oldval, ptdesc_t newval)
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index 5c0ab6b..5377e4c 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -11,6 +11,7 @@
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/cpufeature.h>
+#include <asm/fpsimd.h>
 #include <asm/kvm_asm.h>
 #include <asm/smp_plat.h>
 
@@ -575,6 +576,23 @@ static const struct midr_range erratum_spec_ssbs_list[] = {
 };
 #endif
 
+#ifdef CONFIG_ARM64_ERRATUM_4193714
+static bool has_sme_dvmsync_erratum(const struct arm64_cpu_capabilities *entry,
+				    int scope)
+{
+	if (!id_aa64pfr1_sme(read_sanitised_ftr_reg(SYS_ID_AA64PFR1_EL1)))
+		return false;
+
+	return is_affected_midr_range(entry, scope);
+}
+
+static void cpu_enable_sme_dvmsync(const struct arm64_cpu_capabilities *__unused)
+{
+	if (this_cpu_has_cap(ARM64_WORKAROUND_4193714))
+		sme_enable_dvmsync();
+}
+#endif
+
 #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38
 static const struct midr_range erratum_ac03_cpu_38_list[] = {
 	MIDR_ALL_VERSIONS(MIDR_AMPERE1),
@@ -901,6 +919,18 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
 		.matches = need_arm_si_l1_workaround_4311569,
 	},
 #endif
+#ifdef CONFIG_ARM64_ERRATUM_4193714
+	{
+		.desc = "C1-Pro SME DVMSync early acknowledgement",
+		.capability = ARM64_WORKAROUND_4193714,
+		.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
+		.matches = has_sme_dvmsync_erratum,
+		.cpu_enable = cpu_enable_sme_dvmsync,
+		/* C1-Pro r0p0 - r1p2 (the latter only when REVIDR_EL1[0]==0) */
+		.midr_range = MIDR_RANGE(MIDR_C1_PRO, 0, 0, 1, 2),
+		MIDR_FIXED(MIDR_CPU_VAR_REV(1, 2), BIT(0)),
+	},
+#endif
 #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	{
 		.desc = "ARM errata 2966298, 3117295",
diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index f42ce7b..cb54335 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -21,6 +21,7 @@
 #include <asm/daifflags.h>
 #include <asm/esr.h>
 #include <asm/exception.h>
+#include <asm/fpsimd.h>
 #include <asm/irq_regs.h>
 #include <asm/kprobes.h>
 #include <asm/mmu.h>
@@ -70,6 +71,7 @@ static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
 {
 	enter_from_user_mode(regs);
 	mte_disable_tco_entry(current);
+	sme_enter_from_user_mode();
 }
 
 /*
@@ -83,6 +85,7 @@ static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
 	local_irq_disable();
 	exit_to_user_mode_prepare_legacy(regs);
 	local_daif_mask();
+	sme_exit_to_user_mode();
 	mte_check_tfsr_exit();
 	exit_to_user_mode();
 }
diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 9de1d8a..60a45d6 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -15,6 +15,7 @@
 #include <linux/compiler.h>
 #include <linux/cpu.h>
 #include <linux/cpu_pm.h>
+#include <linux/cpumask.h>
 #include <linux/ctype.h>
 #include <linux/kernel.h>
 #include <linux/linkage.h>
@@ -28,6 +29,7 @@
 #include <linux/sched/task_stack.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
+#include <linux/smp.h>
 #include <linux/stddef.h>
 #include <linux/sysctl.h>
 #include <linux/swab.h>
@@ -1358,6 +1360,83 @@ void do_sve_acc(unsigned long esr, struct pt_regs *regs)
 	put_cpu_fpsimd_context();
 }
 
+#ifdef CONFIG_ARM64_ERRATUM_4193714
+
+/*
+ * SME/CME erratum handling.
+ */
+static cpumask_t sme_dvmsync_cpus;
+
+/*
+ * These helpers are only called from non-preemptible contexts, so
+ * smp_processor_id() is safe here.
+ */
+void sme_set_active(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
+		return;
+
+	cpumask_set_cpu(cpu, mm_cpumask(current->mm));
+
+	/*
+	 * A subsequent (post ERET) SME access may use a stale address
+	 * translation. On C1-Pro, a TLBI+DSB on a different CPU will wait for
+	 * the completion of cpumask_set_cpu() above as it appears in program
+	 * order before the SME access. The post-TLBI+DSB read of mm_cpumask()
+	 * will lead to the IPI being issued.
+	 *
+	 * https://lore.kernel.org/r/ablEXwhfKyJW1i7l@J2N7QTR9R3
+	 */
+}
+
+void sme_clear_active(void)
+{
+	unsigned int cpu = smp_processor_id();
+
+	if (!cpumask_test_cpu(cpu, &sme_dvmsync_cpus))
+		return;
+
+	/*
+	 * With SCTLR_EL1.IESB enabled, the SME memory transactions are
+	 * completed on entering EL1.
+	 */
+	cpumask_clear_cpu(cpu, mm_cpumask(current->mm));
+}
+
+static void sme_dvmsync_ipi(void *unused)
+{
+	/*
+	 * With SCTLR_EL1.IESB on, taking an exception is sufficient to ensure
+	 * the completion of the SME memory accesses, so no need for an
+	 * explicit DSB.
+	 */
+}
+
+void sme_do_dvmsync(const struct cpumask *mask)
+{
+	/*
+	 * This is called from the TLB maintenance functions after the DSB ISH
+	 * to send the hardware DVMSync message. If this CPU sees the mask as
+	 * empty, the remote CPU executing sme_set_active() would have seen
+	 * the DVMSync and no IPI required.
+	 */
+	if (cpumask_empty(mask))
+		return;
+
+	preempt_disable();
+	smp_call_function_many(mask, sme_dvmsync_ipi, NULL, true);
+	preempt_enable();
+}
+
+void sme_enable_dvmsync(void)
+{
+	cpumask_set_cpu(smp_processor_id(), &sme_dvmsync_cpus);
+}
+
+#endif /* CONFIG_ARM64_ERRATUM_4193714 */
+
 /*
  * Trapped SME access
  *
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index c0bf1f4..033643c 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -26,6 +26,7 @@
 #include <linux/reboot.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/cpumask.h>
 #include <linux/cpu.h>
 #include <linux/elfcore.h>
 #include <linux/pm.h>
@@ -340,8 +341,41 @@ void flush_thread(void)
 	flush_gcs();
 }
 
+#ifdef CONFIG_ARM64_ERRATUM_4193714
+
+static void arch_dup_tlbbatch_mask(struct task_struct *dst)
+{
+	/*
+	 * Clear the inherited cpumask with memset() to cover both cases where
+	 * cpumask_var_t is a pointer or an array. It will be allocated lazily
+	 * in sme_dvmsync_add_pending() if CPUMASK_OFFSTACK=y.
+	 */
+	if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
+		memset(&dst->tlb_ubc.arch.cpumask, 0,
+		       sizeof(dst->tlb_ubc.arch.cpumask));
+}
+
+static void arch_release_tlbbatch_mask(struct task_struct *tsk)
+{
+	if (alternative_has_cap_unlikely(ARM64_WORKAROUND_4193714))
+		free_cpumask_var(tsk->tlb_ubc.arch.cpumask);
+}
+
+#else
+
+static void arch_dup_tlbbatch_mask(struct task_struct *dst)
+{
+}
+
+static void arch_release_tlbbatch_mask(struct task_struct *tsk)
+{
+}
+
+#endif /* CONFIG_ARM64_ERRATUM_4193714 */
+
 void arch_release_task_struct(struct task_struct *tsk)
 {
+	arch_release_tlbbatch_mask(tsk);
 	fpsimd_release_task(tsk);
 }
 
@@ -357,6 +391,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 
 	*dst = *src;
 
+	arch_dup_tlbbatch_mask(dst);
+
 	/*
 	 * Drop stale reference to src's sve_state and convert dst to
 	 * non-streaming FPSIMD mode.
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c
index 7e98601..0451f96 100644
--- a/arch/arm64/kernel/sys_compat.c
+++ b/arch/arm64/kernel/sys_compat.c
@@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end)
 			 * We pick the reserved-ASID to minimise the impact.
 			 */
 			__tlbi(aside1is, 0UL);
-			__tlbi_sync_s1ish();
+			__tlbi_sync_s1ish(current->mm);
 		}
 
 		ret = caches_clean_inval_user_pou(start, start + chunk);
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index d47eab0..97987f8 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -397,9 +397,6 @@ void free_initmem(void)
 	WARN_ON(!IS_ALIGNED((unsigned long)lm_init_begin, PAGE_SIZE));
 	WARN_ON(!IS_ALIGNED((unsigned long)lm_init_end, PAGE_SIZE));
 
-	/* Delete __init region from memblock.reserved. */
-	memblock_free(lm_init_begin, lm_init_end - lm_init_begin);
-
 	free_reserved_area(lm_init_begin, lm_init_end,
 			   POISON_FREE_INITMEM, "unused kernel");
 	/*
diff --git a/arch/arm64/tools/cpucaps b/arch/arm64/tools/cpucaps
index b7286d9..811c247 100644
--- a/arch/arm64/tools/cpucaps
+++ b/arch/arm64/tools/cpucaps
@@ -106,6 +106,7 @@
 WORKAROUND_2457168
 WORKAROUND_2645198
 WORKAROUND_2658417
+WORKAROUND_4193714
 WORKAROUND_4311569
 WORKAROUND_AMPERE_AC03_CPU_38
 WORKAROUND_AMPERE_AC04_CPU_23
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index ac714d14..3b042db 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -20,11 +20,11 @@
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
-	select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
+	select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && CPU_HAS_FPU
 	select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PREEMPT_LAZY
-	select ARCH_HAS_PTE_SPECIAL
+	select ARCH_HAS_PTE_SPECIAL if 64BIT
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
@@ -59,16 +59,15 @@
 	select ARCH_KEEP_MEMBLOCK
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
-	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_STACKWALK
 	select ARCH_SUPPORTS_ACPI
 	select ARCH_SUPPORTS_ATOMIC_RMW
-	select ARCH_SUPPORTS_HUGETLBFS
+	select ARCH_SUPPORTS_HUGETLBFS if 64BIT
 	select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
 	select ARCH_SUPPORTS_LTO_CLANG
 	select ARCH_SUPPORTS_LTO_CLANG_THIN
 	select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
-	select ARCH_SUPPORTS_NUMA_BALANCING
+	select ARCH_SUPPORTS_NUMA_BALANCING if NUMA
 	select ARCH_SUPPORTS_PER_VMA_LOCK
 	select ARCH_SUPPORTS_RT
 	select ARCH_SUPPORTS_SCHED_SMT if SMP
@@ -78,10 +77,10 @@
 	select ARCH_USE_MEMTEST
 	select ARCH_USE_QUEUED_RWLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS
-	select ARCH_WANT_DEFAULT_BPF_JIT
+	select ARCH_WANT_DEFAULT_BPF_JIT if HAVE_EBPF_JIT
 	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 	select ARCH_WANT_LD_ORPHAN_WARN
-	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
+	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP if 64BIT
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	select BUILDTIME_TABLE_SORT
@@ -89,13 +88,14 @@
 	select CPU_PM
 	select EDAC_SUPPORT
 	select EFI
+	select GENERIC_ATOMIC64 if 32BIT
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_CPU_DEVICES
 	select GENERIC_CPU_VULNERABILITIES
 	select GENERIC_ENTRY
-	select GENERIC_GETTIMEOFDAY
+	select GENERIC_GETTIMEOFDAY if 64BIT
 	select GENERIC_IOREMAP if !ARCH_IOREMAP
 	select GENERIC_IRQ_MATRIX_ALLOCATOR
 	select GENERIC_IRQ_MULTI_HANDLER
@@ -110,16 +110,16 @@
 	select GENERIC_PCI_IOMAP
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
-	select GENERIC_TIME_VSYSCALL
+	select GENERIC_TIME_VSYSCALL if GENERIC_GETTIMEOFDAY
 	select GPIOLIB
 	select HAS_IOPORT
-	select HAVE_ALIGNED_STRUCT_PAGE
+	select HAVE_ALIGNED_STRUCT_PAGE if 64BIT
 	select HAVE_ARCH_AUDITSYSCALL
-	select HAVE_ARCH_BITREVERSE
+	select HAVE_ARCH_BITREVERSE if 64BIT
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE
-	select HAVE_ARCH_KASAN
-	select HAVE_ARCH_KFENCE
+	select HAVE_ARCH_KASAN if 64BIT
+	select HAVE_ARCH_KFENCE if 64BIT
 	select HAVE_ARCH_KGDB if PERF_EVENTS
 	select HAVE_ARCH_KSTACK_ERASE
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
@@ -127,8 +127,8 @@
 	select HAVE_ARCH_SECCOMP
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
-	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
-	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT
+	select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
 	select HAVE_ASM_MODVERSIONS
 	select HAVE_CMPXCHG_DOUBLE
 	select HAVE_CMPXCHG_LOCAL
@@ -142,7 +142,7 @@
 	select HAVE_FTRACE_REGS_HAVING_PT_REGS
 	select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
-	select HAVE_EBPF_JIT
+	select HAVE_EBPF_JIT if 64BIT
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS if !ARCH_STRICT_ALIGN
 	select HAVE_EXIT_THREAD
 	select HAVE_GENERIC_TIF_BITS
@@ -165,9 +165,9 @@
 	select HAVE_LIVEPATCH
 	select HAVE_MOD_ARCH_SPECIFIC
 	select HAVE_NMI
-	select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB
+	select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && 64BIT
 	select HAVE_PCI
-	select HAVE_PERF_EVENTS
+	select HAVE_PERF_EVENTS if 64BIT
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
@@ -209,18 +209,50 @@
 	select SYSCTL_ARCH_UNALIGN_ALLOW
 	select SYSCTL_ARCH_UNALIGN_NO_WARN
 	select SYSCTL_EXCEPTION_TRACE
-	select SWIOTLB
+	select SWIOTLB if 64BIT
 	select TRACE_IRQFLAGS_SUPPORT
 	select USE_PERCPU_NUMA_NODE_ID
 	select USER_STACKTRACE_SUPPORT
 	select VDSO_GETRANDOM
-	select ZONE_DMA32
+	select ZONE_DMA32 if 64BIT
+
+menu "Kernel type and options"
+
+choice
+	prompt "Kernel type"
 
 config 32BIT
-	bool
+	bool "32-bit kernel"
+	help
+	  Select this option if you want to build a 32-bit kernel.
 
 config 64BIT
-	def_bool y
+	bool "64-bit kernel"
+	help
+	  Select this option if you want to build a 64-bit kernel.
+
+endchoice
+
+if 32BIT
+
+choice
+	prompt "32-bit kernel sub-type"
+
+config 32BIT_REDUCED
+	bool "32-bit kernel for LA32R"
+	help
+	  Select this option if you want to build a 32-bit kernel for
+	  LoongArch32 Reduced (LA32R).
+
+config 32BIT_STANDARD
+	bool "32-bit kernel for LA32S"
+	help
+	  Select this option if you want to build a 32-bit kernel for
+	  LoongArch32 Standard (LA32S).
+
+endchoice
+
+endif
 
 config GENERIC_BUG
 	def_bool y
@@ -313,10 +345,13 @@
 	depends on RUST
 	def_bool $(rustc-option,-Cllvm-args=--loongarch-annotate-tablejump)
 
-menu "Kernel type and options"
-
 source "kernel/Kconfig.hz"
 
+config HIGHMEM
+	bool "High Memory Support"
+	depends on 32BIT
+	select KMAP_LOCAL
+
 choice
 	prompt "Page Table Layout"
 	default 16KB_2LEVEL if 32BIT
@@ -326,8 +361,17 @@
 	  of page size and page table levels. The size of virtual memory
 	  address space are determined by the page table layout.
 
+config 4KB_2LEVEL
+	bool "4KB with 2 levels"
+	select HAVE_PAGE_SIZE_4KB
+	select PGTABLE_2LEVEL
+	help
+	  This option selects 4KB page size with 2 level page tables, which
+	  support a maximum of 32 bits of application virtual memory.
+
 config 4KB_3LEVEL
 	bool "4KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_4KB
 	select PGTABLE_3LEVEL
 	help
@@ -336,6 +380,7 @@
 
 config 4KB_4LEVEL
 	bool "4KB with 4 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_4KB
 	select PGTABLE_4LEVEL
 	help
@@ -352,6 +397,7 @@
 
 config 16KB_3LEVEL
 	bool "16KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_16KB
 	select PGTABLE_3LEVEL
 	help
@@ -368,6 +414,7 @@
 
 config 64KB_3LEVEL
 	bool "64KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_64KB
 	select PGTABLE_3LEVEL
 	help
@@ -465,6 +512,7 @@
 
 config SMP
 	bool "Multi-Processing support"
+	depends on 64BIT
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, say N. If you have a system with more
@@ -503,6 +551,7 @@
 config NUMA
 	bool "NUMA Support"
 	select SMP
+	depends on 64BIT
 	help
 	  Say Y to compile the kernel with NUMA (Non-Uniform Memory Access)
 	  support.  This option improves performance on systems with more
@@ -585,7 +634,7 @@
 
 config CPU_HAS_LSX
 	bool "Support for the Loongson SIMD Extension"
-	depends on AS_HAS_LSX_EXTENSION
+	depends on AS_HAS_LSX_EXTENSION && 64BIT
 	help
 	  Loongson SIMD Extension (LSX) introduces 128 bit wide vector registers
 	  and a set of SIMD instructions to operate on them. When this option
@@ -600,7 +649,7 @@
 config CPU_HAS_LASX
 	bool "Support for the Loongson Advanced SIMD Extension"
 	depends on CPU_HAS_LSX
-	depends on AS_HAS_LASX_EXTENSION
+	depends on AS_HAS_LASX_EXTENSION && 64BIT
 	help
 	  Loongson Advanced SIMD Extension (LASX) introduces 256 bit wide vector
 	  registers and a set of SIMD instructions to operate on them. When this
@@ -614,7 +663,7 @@
 
 config CPU_HAS_LBT
 	bool "Support for the Loongson Binary Translation Extension"
-	depends on AS_HAS_LBT_EXTENSION
+	depends on AS_HAS_LBT_EXTENSION && 64BIT
 	help
 	  Loongson Binary Translation (LBT) introduces 4 scratch registers (SCR0
 	  to SCR3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop).
@@ -642,13 +691,13 @@
 	select HAVE_IMA_KEXEC if IMA
 
 config ARCH_SUPPORTS_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 
 config ARCH_DEFAULT_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 
 config ARCH_SELECTS_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 	depends on CRASH_DUMP
 	select RELOCATABLE
 
@@ -657,6 +706,7 @@
 
 config RELOCATABLE
 	bool "Relocatable kernel"
+	depends on 64BIT
 	select ARCH_HAS_RELR
 	help
 	  This builds the kernel as a Position Independent Executable (PIE),
@@ -693,7 +743,7 @@
 
 config PARAVIRT
 	bool "Enable paravirtualization code"
-	depends on AS_HAS_LVZ_EXTENSION
+	depends on AS_HAS_LVZ_EXTENSION && 64BIT
 	select HAVE_PV_STEAL_CLOCK_GEN
 	help
 	  This changes the kernel so it can modify itself when it is run
@@ -722,7 +772,7 @@
 	depends on !NUMA
 
 config ARCH_SPARSEMEM_ENABLE
-	def_bool y
+	def_bool 64BIT
 	select SPARSEMEM_VMEMMAP_ENABLE
 	help
 	  Say Y to support efficient handling of sparse physical memory,
@@ -739,10 +789,12 @@
 	default y
 
 config ARCH_MMAP_RND_BITS_MIN
-	default 12
+	default 10 if 32BIT
+	default 12 if 64BIT
 
 config ARCH_MMAP_RND_BITS_MAX
-	default 18
+	default 15 if 32BIT
+	default 20 if 64BIT
 
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index 8d45b86..47516ae 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -25,6 +25,7 @@
 #
 # Select the object file format to substitute into the linker script.
 #
+32bit-tool-archpref	= loongarch32
 64bit-tool-archpref	= loongarch64
 32bit-bfd		= elf32-loongarch
 64bit-bfd		= elf64-loongarch
@@ -51,7 +52,10 @@
 CC_FLAGS_FTRACE := -fpatchable-function-entry=2
 endif
 
-ifdef CONFIG_64BIT
+ifdef CONFIG_32BIT
+tool-archpref		= $(32bit-tool-archpref)
+UTS_MACHINE		:= loongarch32
+else
 tool-archpref		= $(64bit-tool-archpref)
 UTS_MACHINE		:= loongarch64
 endif
@@ -62,9 +66,19 @@
   endif
 endif
 
+ifdef CONFIG_32BIT
+ifdef CONFIG_32BIT_STANDARD
+ld-emul			= $(32bit-emul)
+cflags-y		+= -march=la32v1.0 -mabi=ilp32s -mcmodel=normal
+else  # CONFIG_32BIT_REDUCED
+ld-emul			= $(32bit-emul)
+cflags-y		+= -march=la32rv1.0 -mabi=ilp32s -mcmodel=normal
+endif
+endif
+
 ifdef CONFIG_64BIT
 ld-emul			= $(64bit-emul)
-cflags-y		+= -mabi=lp64s -mcmodel=normal
+cflags-y		+= -march=loongarch64 -mabi=lp64s -mcmodel=normal
 endif
 
 cflags-y			+= -pipe $(CC_FLAGS_NO_FPU)
@@ -140,7 +154,12 @@
 cflags-y += -fno-builtin-memcpy -fno-builtin-memmove -fno-builtin-memset
 endif
 
+ifdef CONFIG_32BIT
+load-y		= 0xa0200000
+else
 load-y		= 0x9000000000200000
+endif
+
 bootvars-y	= VMLINUX_LOAD_ADDRESS=$(load-y)
 
 drivers-$(CONFIG_PCI)		+= arch/loongarch/pci/
diff --git a/arch/loongarch/boot/Makefile b/arch/loongarch/boot/Makefile
index 4e1c374..8b6d9b4 100644
--- a/arch/loongarch/boot/Makefile
+++ b/arch/loongarch/boot/Makefile
@@ -20,7 +20,13 @@
 	$(call if_changed,objcopy)
 
 EFI_ZBOOT_PAYLOAD      := vmlinux.efi
+
+ifdef CONFIG_32BIT
+EFI_ZBOOT_BFD_TARGET   := elf32-loongarch
+EFI_ZBOOT_MACH_TYPE    := LOONGARCH32
+else
 EFI_ZBOOT_BFD_TARGET   := elf64-loongarch
 EFI_ZBOOT_MACH_TYPE    := LOONGARCH64
+endif
 
 include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot
diff --git a/arch/loongarch/include/asm/cacheflush.h b/arch/loongarch/include/asm/cacheflush.h
index f8754d0..190651b 100644
--- a/arch/loongarch/include/asm/cacheflush.h
+++ b/arch/loongarch/include/asm/cacheflush.h
@@ -32,8 +32,22 @@ static inline unsigned int cpu_last_level_cache_line_size(void)
 }
 
 asmlinkage void __flush_cache_all(void);
-void local_flush_icache_range(unsigned long start, unsigned long end);
 
+/*
+ * LoongArch maintains ICache/DCache coherency by hardware,
+ * we just need "ibar" to avoid instruction hazard here.
+ */
+static inline void local_flush_icache_all(void)
+{
+	asm volatile ("ibar\t0\n"::);
+}
+
+static inline void local_flush_icache_range(unsigned long start, unsigned long end)
+{
+	asm volatile ("ibar\t0\n"::);
+}
+
+#define flush_icache_all	local_flush_icache_all
 #define flush_icache_range	local_flush_icache_range
 #define flush_icache_user_range	local_flush_icache_range
 
diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h
index 8eefe7a..62059c5 100644
--- a/arch/loongarch/include/asm/cpu-features.h
+++ b/arch/loongarch/include/asm/cpu-features.h
@@ -35,6 +35,7 @@
  */
 #define cpu_has_cpucfg		cpu_opt(LOONGARCH_CPU_CPUCFG)
 #define cpu_has_lam		cpu_opt(LOONGARCH_CPU_LAM)
+#define cpu_has_lam_bh		cpu_opt(LOONGARCH_CPU_LAM_BH)
 #define cpu_has_scq		cpu_opt(LOONGARCH_CPU_SCQ)
 #define cpu_has_ual		cpu_opt(LOONGARCH_CPU_UAL)
 #define cpu_has_fpu		cpu_opt(LOONGARCH_CPU_FPU)
diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h
index 1e60ab2..91b9693 100644
--- a/arch/loongarch/include/asm/cpu.h
+++ b/arch/loongarch/include/asm/cpu.h
@@ -95,40 +95,42 @@ static inline char *id_to_core_name(unsigned int id)
  */
 #define CPU_FEATURE_CPUCFG		0	/* CPU has CPUCFG */
 #define CPU_FEATURE_LAM			1	/* CPU has Atomic instructions */
-#define CPU_FEATURE_SCQ			2	/* CPU has SC.Q instruction */
-#define CPU_FEATURE_UAL			3	/* CPU supports unaligned access */
-#define CPU_FEATURE_FPU			4	/* CPU has FPU */
-#define CPU_FEATURE_LSX			5	/* CPU has LSX (128-bit SIMD) */
-#define CPU_FEATURE_LASX		6	/* CPU has LASX (256-bit SIMD) */
-#define CPU_FEATURE_CRC32		7	/* CPU has CRC32 instructions */
-#define CPU_FEATURE_COMPLEX		8	/* CPU has Complex instructions */
-#define CPU_FEATURE_CRYPTO		9	/* CPU has Crypto instructions */
-#define CPU_FEATURE_LVZ			10	/* CPU has Virtualization extension */
-#define CPU_FEATURE_LBT_X86		11	/* CPU has X86 Binary Translation */
-#define CPU_FEATURE_LBT_ARM		12	/* CPU has ARM Binary Translation */
-#define CPU_FEATURE_LBT_MIPS		13	/* CPU has MIPS Binary Translation */
-#define CPU_FEATURE_TLB			14	/* CPU has TLB */
-#define CPU_FEATURE_CSR			15	/* CPU has CSR */
-#define CPU_FEATURE_IOCSR		16	/* CPU has IOCSR */
-#define CPU_FEATURE_WATCH		17	/* CPU has watchpoint registers */
-#define CPU_FEATURE_VINT		18	/* CPU has vectored interrupts */
-#define CPU_FEATURE_CSRIPI		19	/* CPU has CSR-IPI */
-#define CPU_FEATURE_EXTIOI		20	/* CPU has EXT-IOI */
-#define CPU_FEATURE_PREFETCH		21	/* CPU has prefetch instructions */
-#define CPU_FEATURE_PMP			22	/* CPU has perfermance counter */
-#define CPU_FEATURE_SCALEFREQ		23	/* CPU supports cpufreq scaling */
-#define CPU_FEATURE_FLATMODE		24	/* CPU has flat mode */
-#define CPU_FEATURE_EIODECODE		25	/* CPU has EXTIOI interrupt pin decode mode */
-#define CPU_FEATURE_GUESTID		26	/* CPU has GuestID feature */
-#define CPU_FEATURE_HYPERVISOR		27	/* CPU has hypervisor (running in VM) */
-#define CPU_FEATURE_PTW			28	/* CPU has hardware page table walker */
-#define CPU_FEATURE_LSPW		29	/* CPU has LSPW (lddir/ldpte instructions) */
-#define CPU_FEATURE_MSGINT		30	/* CPU has MSG interrupt */
-#define CPU_FEATURE_AVECINT		31	/* CPU has AVEC interrupt */
-#define CPU_FEATURE_REDIRECTINT		32	/* CPU has interrupt remapping */
+#define CPU_FEATURE_LAM_BH		2	/* CPU has AM{SWAP/ADD}[_DB].{B/H} instructions */
+#define CPU_FEATURE_SCQ			3	/* CPU has SC.Q instruction */
+#define CPU_FEATURE_UAL			4	/* CPU supports unaligned access */
+#define CPU_FEATURE_FPU			5	/* CPU has FPU */
+#define CPU_FEATURE_LSX			6	/* CPU has LSX (128-bit SIMD) */
+#define CPU_FEATURE_LASX		7	/* CPU has LASX (256-bit SIMD) */
+#define CPU_FEATURE_CRC32		8	/* CPU has CRC32 instructions */
+#define CPU_FEATURE_COMPLEX		9	/* CPU has Complex instructions */
+#define CPU_FEATURE_CRYPTO		10	/* CPU has Crypto instructions */
+#define CPU_FEATURE_LVZ			11	/* CPU has Virtualization extension */
+#define CPU_FEATURE_LBT_X86		12	/* CPU has X86 Binary Translation */
+#define CPU_FEATURE_LBT_ARM		13	/* CPU has ARM Binary Translation */
+#define CPU_FEATURE_LBT_MIPS		14	/* CPU has MIPS Binary Translation */
+#define CPU_FEATURE_TLB			15	/* CPU has TLB */
+#define CPU_FEATURE_CSR			16	/* CPU has CSR */
+#define CPU_FEATURE_IOCSR		17	/* CPU has IOCSR */
+#define CPU_FEATURE_WATCH		18	/* CPU has watchpoint registers */
+#define CPU_FEATURE_VINT		19	/* CPU has vectored interrupts */
+#define CPU_FEATURE_CSRIPI		20	/* CPU has CSR-IPI */
+#define CPU_FEATURE_EXTIOI		21	/* CPU has EXT-IOI */
+#define CPU_FEATURE_PREFETCH		22	/* CPU has prefetch instructions */
+#define CPU_FEATURE_PMP			23	/* CPU has perfermance counter */
+#define CPU_FEATURE_SCALEFREQ		24	/* CPU supports cpufreq scaling */
+#define CPU_FEATURE_FLATMODE		25	/* CPU has flat mode */
+#define CPU_FEATURE_EIODECODE		26	/* CPU has EXTIOI interrupt pin decode mode */
+#define CPU_FEATURE_GUESTID		27	/* CPU has GuestID feature */
+#define CPU_FEATURE_HYPERVISOR		28	/* CPU has hypervisor (running in VM) */
+#define CPU_FEATURE_PTW			29	/* CPU has hardware page table walker */
+#define CPU_FEATURE_LSPW		30	/* CPU has LSPW (lddir/ldpte instructions) */
+#define CPU_FEATURE_MSGINT		31	/* CPU has MSG interrupt */
+#define CPU_FEATURE_AVECINT		32	/* CPU has AVEC interrupt */
+#define CPU_FEATURE_REDIRECTINT		33	/* CPU has interrupt remapping */
 
 #define LOONGARCH_CPU_CPUCFG		BIT_ULL(CPU_FEATURE_CPUCFG)
 #define LOONGARCH_CPU_LAM		BIT_ULL(CPU_FEATURE_LAM)
+#define LOONGARCH_CPU_LAM_BH		BIT_ULL(CPU_FEATURE_LAM_BH)
 #define LOONGARCH_CPU_SCQ		BIT_ULL(CPU_FEATURE_SCQ)
 #define LOONGARCH_CPU_UAL		BIT_ULL(CPU_FEATURE_UAL)
 #define LOONGARCH_CPU_FPU		BIT_ULL(CPU_FEATURE_FPU)
diff --git a/arch/loongarch/include/asm/fixmap.h b/arch/loongarch/include/asm/fixmap.h
index d2e55ae..dce2da6 100644
--- a/arch/loongarch/include/asm/fixmap.h
+++ b/arch/loongarch/include/asm/fixmap.h
@@ -8,10 +8,19 @@
 #ifndef _ASM_FIXMAP_H
 #define _ASM_FIXMAP_H
 
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_size.h>
+#endif
+
 #define NR_FIX_BTMAPS 64
 
 enum fixed_addresses {
 	FIX_HOLE,
+#ifdef CONFIG_HIGHMEM
+	FIX_KMAP_BEGIN,
+	FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_MAX_IDX * NR_CPUS) - 1,
+#endif
 	FIX_EARLYCON_MEM_BASE,
 	__end_of_fixed_addresses
 };
@@ -25,4 +34,9 @@ extern void __set_fixmap(enum fixed_addresses idx,
 
 #include <asm-generic/fixmap.h>
 
+/*
+ * Called from pagetable_init()
+ */
+extern void fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base);
+
 #endif
diff --git a/arch/loongarch/include/asm/highmem.h b/arch/loongarch/include/asm/highmem.h
new file mode 100644
index 0000000..e6d7a66
--- /dev/null
+++ b/arch/loongarch/include/asm/highmem.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * highmem.h: virtual kernel memory mappings for high memory
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+#ifndef _ASM_HIGHMEM_H
+#define _ASM_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <asm/kmap_size.h>
+
+#ifndef __ASSEMBLER__
+
+extern pte_t *pkmap_page_table;
+
+#define ARCH_HAS_KMAP_FLUSH_TLB
+void kmap_flush_tlb(unsigned long addr);
+
+#endif /* !__ASSEMBLER__ */
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP 1024
+#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
+#define PKMAP_NR(virt)	((virt - PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)	(PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+#define flush_cache_kmaps() do {} while (0)
+
+#define arch_kmap_local_post_map(vaddr, pteval)	local_flush_tlb_one(vaddr)
+#define arch_kmap_local_post_unmap(vaddr)	local_flush_tlb_one(vaddr)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_HIGHMEM_H */
diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
index f9f2070..76b7235 100644
--- a/arch/loongarch/include/asm/inst.h
+++ b/arch/loongarch/include/asm/inst.h
@@ -36,6 +36,7 @@
 
 enum reg0i15_op {
 	break_op	= 0x54,
+	dbar_op		= 0x70e4,
 };
 
 enum reg0i26_op {
@@ -194,6 +195,10 @@ enum reg3_op {
 	fstxs_op	= 0x7070,
 	fstxd_op	= 0x7078,
 	scq_op		= 0x70ae,
+	amswapb_op	= 0x70b8,
+	amswaph_op	= 0x70b9,
+	amaddb_op	= 0x70ba,
+	amaddh_op	= 0x70bb,
 	amswapw_op	= 0x70c0,
 	amswapd_op	= 0x70c1,
 	amaddw_op	= 0x70c2,
@@ -543,6 +548,7 @@ static inline void emit_##NAME(union loongarch_instruction *insn,	\
 }
 
 DEF_EMIT_REG0I15_FORMAT(break, break_op)
+DEF_EMIT_REG0I15_FORMAT(dbar, dbar_op)
 
 /* like emit_break(imm) but returns a constant expression */
 #define __emit_break(imm)	((u32)((imm) | (break_op << 15)))
@@ -763,6 +769,8 @@ DEF_EMIT_REG3_FORMAT(stxb, stxb_op)
 DEF_EMIT_REG3_FORMAT(stxh, stxh_op)
 DEF_EMIT_REG3_FORMAT(stxw, stxw_op)
 DEF_EMIT_REG3_FORMAT(stxd, stxd_op)
+DEF_EMIT_REG3_FORMAT(amaddb, amaddb_op)
+DEF_EMIT_REG3_FORMAT(amaddh, amaddh_op)
 DEF_EMIT_REG3_FORMAT(amaddw, amaddw_op)
 DEF_EMIT_REG3_FORMAT(amaddd, amaddd_op)
 DEF_EMIT_REG3_FORMAT(amandw, amandw_op)
@@ -771,6 +779,8 @@ DEF_EMIT_REG3_FORMAT(amorw, amorw_op)
 DEF_EMIT_REG3_FORMAT(amord, amord_op)
 DEF_EMIT_REG3_FORMAT(amxorw, amxorw_op)
 DEF_EMIT_REG3_FORMAT(amxord, amxord_op)
+DEF_EMIT_REG3_FORMAT(amswapb, amswapb_op)
+DEF_EMIT_REG3_FORMAT(amswaph, amswaph_op)
 DEF_EMIT_REG3_FORMAT(amswapw, amswapw_op)
 DEF_EMIT_REG3_FORMAT(amswapd, amswapd_op)
 
diff --git a/arch/loongarch/include/asm/irq_work.h b/arch/loongarch/include/asm/irq_work.h
index d63076e..63aee03 100644
--- a/arch/loongarch/include/asm/irq_work.h
+++ b/arch/loongarch/include/asm/irq_work.h
@@ -4,7 +4,7 @@
 
 static inline bool arch_irq_work_has_interrupt(void)
 {
-	return IS_ENABLED(CONFIG_SMP);
+	return IS_ENABLED(CONFIG_SMP) && cpu_opt(LOONGARCH_CPU_CSRIPI);
 }
 
 #endif /* _ASM_LOONGARCH_IRQ_WORK_H */
diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h
index dcaecf6..7ef4ae3 100644
--- a/arch/loongarch/include/asm/jump_label.h
+++ b/arch/loongarch/include/asm/jump_label.h
@@ -13,6 +13,8 @@
 #include <linux/stringify.h>
 #include <asm/asm.h>
 
+#define HAVE_JUMP_LABEL_BATCH
+
 #define JUMP_LABEL_NOP_SIZE	4
 
 #ifdef CONFIG_32BIT
diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h
index 79235f4..b9d61f7 100644
--- a/arch/loongarch/include/asm/page.h
+++ b/arch/loongarch/include/asm/page.h
@@ -36,10 +36,6 @@ extern unsigned long shm_align_mask;
 
 struct page;
 struct vm_area_struct;
-void copy_user_highpage(struct page *to, struct page *from,
-	      unsigned long vaddr, struct vm_area_struct *vma);
-
-#define __HAVE_ARCH_COPY_USER_HIGHPAGE
 
 typedef struct { unsigned long pte; } pte_t;
 #define pte_val(x)	((x).pte)
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index 155f70e..2a0b63a 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -23,6 +23,10 @@
 #include <asm-generic/pgtable-nop4d.h>
 #endif
 
+#ifdef CONFIG_HIGHMEM
+#include <asm/highmem.h>
+#endif
+
 #if CONFIG_PGTABLE_LEVELS == 2
 #define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - PTRLOG))
 #elif CONFIG_PGTABLE_LEVELS == 3
@@ -77,7 +81,15 @@ struct vm_area_struct;
 #ifdef CONFIG_32BIT
 
 #define VMALLOC_START	(vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE))
+
+#ifdef CONFIG_HIGHMEM
+#define VMALLOC_END	(PKMAP_BASE - (2 * PAGE_SIZE))
+#else
 #define VMALLOC_END	(FIXADDR_START - (2 * PAGE_SIZE))
+#endif
+
+#define PKMAP_BASE	(PKMAP_END - (PAGE_SIZE * LAST_PKMAP))
+#define PKMAP_END	((FIXADDR_START) & ~((LAST_PKMAP << PAGE_SHIFT)-1))
 
 #endif
 
diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/include/asm/processor.h
index c3bc44b..ce8b953 100644
--- a/arch/loongarch/include/asm/processor.h
+++ b/arch/loongarch/include/asm/processor.h
@@ -80,10 +80,10 @@ BUILD_FPR_ACCESS(32)
 BUILD_FPR_ACCESS(64)
 
 struct loongarch_fpu {
+	union fpureg	fpr[NUM_FPU_REGS];
 	uint64_t	fcc;	/* 8x8 */
 	uint32_t	fcsr;
 	uint32_t	ftop;
-	union fpureg	fpr[NUM_FPU_REGS];
 };
 
 struct loongarch_lbt {
diff --git a/arch/loongarch/include/asm/stackprotector.h b/arch/loongarch/include/asm/stackprotector.h
index a1a9657..42f6c3f 100644
--- a/arch/loongarch/include/asm/stackprotector.h
+++ b/arch/loongarch/include/asm/stackprotector.h
@@ -12,9 +12,6 @@
 #ifndef _ASM_STACKPROTECTOR_H
 #define _ASM_STACKPROTECTOR_H
 
-#include <linux/random.h>
-#include <linux/version.h>
-
 extern unsigned long __stack_chk_guard;
 
 /*
@@ -25,11 +22,7 @@ extern unsigned long __stack_chk_guard;
  */
 static __always_inline void boot_init_stack_canary(void)
 {
-	unsigned long canary;
-
-	/* Try to get a semi random initial value. */
-	get_random_bytes(&canary, sizeof(canary));
-	canary ^= LINUX_VERSION_CODE;
+	unsigned long canary = get_random_canary();
 
 	current->stack_canary = canary;
 	__stack_chk_guard = current->stack_canary;
diff --git a/arch/loongarch/include/asm/syscall.h b/arch/loongarch/include/asm/syscall.h
index 81d2733..df8ea223 100644
--- a/arch/loongarch/include/asm/syscall.h
+++ b/arch/loongarch/include/asm/syscall.h
@@ -78,7 +78,11 @@ static inline void syscall_set_arguments(struct task_struct *task,
 
 static inline int syscall_get_arch(struct task_struct *task)
 {
+#ifdef CONFIG_32BIT
+	return AUDIT_ARCH_LOONGARCH32;
+#else
 	return AUDIT_ARCH_LOONGARCH64;
+#endif
 }
 
 static inline bool arch_syscall_is_vdso_sigreturn(struct pt_regs *regs)
diff --git a/arch/loongarch/include/uapi/asm/hwcap.h b/arch/loongarch/include/uapi/asm/hwcap.h
index 49519b4..90e9611 100644
--- a/arch/loongarch/include/uapi/asm/hwcap.h
+++ b/arch/loongarch/include/uapi/asm/hwcap.h
@@ -19,5 +19,6 @@
 #define HWCAP_LOONGARCH_PTW		(1 << 13)
 #define HWCAP_LOONGARCH_LSPW		(1 << 14)
 #define HWCAP_LOONGARCH_SCQ		(1 << 15)
+#define HWCAP_LOONGARCH_LAM_BH		(1 << 16)
 
 #endif /* _UAPI_ASM_HWCAP_H */
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 657bbae6c..74d31f2 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
+#include <linux/cpu.h>
 #include <linux/smp.h>
 #include <linux/stddef.h>
 #include <linux/export.h>
@@ -177,6 +178,10 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 		c->options |= LOONGARCH_CPU_LAM;
 		elf_hwcap |= HWCAP_LOONGARCH_LAM;
 	}
+	if (config & CPUCFG2_LAM_BH) {
+		c->options |= LOONGARCH_CPU_LAM_BH;
+		elf_hwcap |= HWCAP_LOONGARCH_LAM_BH;
+	}
 	if (config & CPUCFG2_SCQ) {
 		c->options |= LOONGARCH_CPU_SCQ;
 		elf_hwcap |= HWCAP_LOONGARCH_SCQ;
@@ -402,3 +407,9 @@ void cpu_probe(void)
 
 	cpu_report();
 }
+
+ssize_t cpu_show_spectre_v1(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	return sysfs_emit(buf, "Mitigation: __user pointer sanitization\n");
+}
diff --git a/arch/loongarch/kernel/fpu.S b/arch/loongarch/kernel/fpu.S
index f225dcc..bf7d6b8 100644
--- a/arch/loongarch/kernel/fpu.S
+++ b/arch/loongarch/kernel/fpu.S
@@ -97,7 +97,7 @@
 	.endm
 
 #ifdef CONFIG_32BIT
-	.macro sc_save_fcc thread tmp0 tmp1
+	.macro sc_save_fcc base tmp0 tmp1
 	movcf2gr	\tmp0, $fcc0
 	move		\tmp1, \tmp0
 	movcf2gr	\tmp0, $fcc1
@@ -106,7 +106,7 @@
 	bstrins.w	\tmp1, \tmp0, 23, 16
 	movcf2gr	\tmp0, $fcc3
 	bstrins.w	\tmp1, \tmp0, 31, 24
-	EX	st.w	\tmp1, \thread, THREAD_FCC
+	EX	st.w	\tmp1, \base, 0
 	movcf2gr	\tmp0, $fcc4
 	move		\tmp1, \tmp0
 	movcf2gr	\tmp0, $fcc5
@@ -115,11 +115,11 @@
 	bstrins.w	\tmp1, \tmp0, 23, 16
 	movcf2gr	\tmp0, $fcc7
 	bstrins.w	\tmp1, \tmp0, 31, 24
-	EX	st.w	\tmp1, \thread, (THREAD_FCC + 4)
+	EX	st.w	\tmp1, \base, 4
 	.endm
 
-	.macro sc_restore_fcc thread tmp0 tmp1
-	EX	ld.w	\tmp0, \thread, THREAD_FCC
+	.macro sc_restore_fcc base tmp0 tmp1
+	EX	ld.w	\tmp0, \base, 0
 	bstrpick.w	\tmp1, \tmp0, 7, 0
 	movgr2cf	$fcc0, \tmp1
 	bstrpick.w	\tmp1, \tmp0, 15, 8
@@ -128,7 +128,7 @@
 	movgr2cf	$fcc2, \tmp1
 	bstrpick.w	\tmp1, \tmp0, 31, 24
 	movgr2cf	$fcc3, \tmp1
-	EX	ld.w	\tmp0, \thread, (THREAD_FCC + 4)
+	EX	ld.w	\tmp0, \base, 4
 	bstrpick.w	\tmp1, \tmp0, 7, 0
 	movgr2cf	$fcc4, \tmp1
 	bstrpick.w	\tmp1, \tmp0, 15, 8
diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c
index 1a72808..0b9228b 100644
--- a/arch/loongarch/kernel/inst.c
+++ b/arch/loongarch/kernel/inst.c
@@ -209,6 +209,9 @@ int larch_insn_write(void *addr, u32 insn)
 	int ret;
 	unsigned long flags = 0;
 
+	if ((unsigned long)addr & 3)
+		return -EINVAL;
+
 	raw_spin_lock_irqsave(&patch_lock, flags);
 	ret = copy_to_kernel_nofault(addr, &insn, LOONGARCH_INSN_SIZE);
 	raw_spin_unlock_irqrestore(&patch_lock, flags);
@@ -221,9 +224,6 @@ int larch_insn_patch_text(void *addr, u32 insn)
 	int ret;
 	u32 *tp = addr;
 
-	if ((unsigned long)tp & 3)
-		return -EINVAL;
-
 	ret = larch_insn_write(tp, insn);
 	if (!ret)
 		flush_icache_range((unsigned long)tp,
diff --git a/arch/loongarch/kernel/jump_label.c b/arch/loongarch/kernel/jump_label.c
index 3189121..24a3f4d 100644
--- a/arch/loongarch/kernel/jump_label.c
+++ b/arch/loongarch/kernel/jump_label.c
@@ -6,9 +6,10 @@
  */
 #include <linux/kernel.h>
 #include <linux/jump_label.h>
+#include <asm/cacheflush.h>
 #include <asm/inst.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)
 {
 	u32 insn;
 	void *addr = (void *)jump_entry_code(entry);
@@ -18,5 +19,12 @@ void arch_jump_label_transform(struct jump_entry *entry, enum jump_label_type ty
 	else
 		insn = larch_insn_gen_nop();
 
-	larch_insn_patch_text(addr, insn);
+	larch_insn_write(addr, insn);
+
+	return true;
+}
+
+void arch_jump_label_transform_apply(void)
+{
+	flush_icache_all();
 }
diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c
index a8127e8..d4ce5b5 100644
--- a/arch/loongarch/kernel/proc.c
+++ b/arch/loongarch/kernel/proc.c
@@ -64,6 +64,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 		seq_puts(m, " cpucfg");
 	if (cpu_has_lam)
 		seq_puts(m, " lam");
+	if (cpu_has_lam_bh)
+		seq_puts(m, " lam_bh");
 	if (cpu_has_scq)
 		seq_puts(m, " scq");
 	if (cpu_has_ual)
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index ac3a0ba..5505fc35 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -136,6 +136,8 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 		return 0;
 	}
 
+	dst->thread.fpu.fcsr =  src->thread.fpu.fcsr;
+
 	if (!used_math())
 		memcpy(dst, src, offsetof(struct task_struct, thread.fpu.fpr));
 	else
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index 82aa3f0..16f6a9b 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -128,24 +128,28 @@ static inline __init unsigned long get_random_boot(void)
 
 static int __init nokaslr(char *p)
 {
-	pr_info("KASLR is disabled.\n");
-
-	return 0; /* Print a notice and silence the boot warning */
+	return 0; /* Just silence the boot warning */
 }
 early_param("nokaslr", nokaslr);
 
+#define KASLR_DISABLED_MESSAGE "KASLR is disabled by %s in %s cmdline.\n"
+
 static inline __init bool kaslr_disabled(void)
 {
 	char *str;
 	const char *builtin_cmdline = CONFIG_CMDLINE;
 
 	str = strstr(builtin_cmdline, "nokaslr");
-	if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
+	if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
+		pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "built-in");
 		return true;
+	}
 
 	str = strstr(boot_command_line, "nokaslr");
-	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
+		pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "bootloader");
 		return true;
+	}
 
 #ifdef CONFIG_HIBERNATION
 	str = strstr(builtin_cmdline, "nohibernate");
@@ -165,17 +169,23 @@ static inline __init bool kaslr_disabled(void)
 		return false;
 
 	str = strstr(builtin_cmdline, "resume=");
-	if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' '))
+	if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
+		pr_info(KASLR_DISABLED_MESSAGE, "\'resume=\'", "built-in");
 		return true;
+	}
 
 	str = strstr(boot_command_line, "resume=");
-	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
+		pr_info(KASLR_DISABLED_MESSAGE, "\'resume=\'", "bootloader");
 		return true;
+	}
 #endif
 
 	str = strstr(boot_command_line, "kexec_file");
-	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' '))
+	if (str == boot_command_line || (str > boot_command_line && *(str - 1) == ' ')) {
+		pr_info(KASLR_DISABLED_MESSAGE, "\'kexec_file\'", "bootloader");
 		return true;
+	}
 
 	return false;
 }
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index 85da7e0..94c1c3b 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -9,6 +9,7 @@
 #include <linux/entry-common.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
+#include <linux/nospec.h>
 #include <linux/objtool.h>
 #include <linux/randomize_kstack.h>
 #include <linux/syscalls.h>
@@ -74,7 +75,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
 	add_random_kstack_offset();
 
 	if (nr < NR_syscalls) {
-		syscall_fn = sys_call_table[nr];
+		syscall_fn = sys_call_table[array_index_nospec(nr, NR_syscalls)];
 		regs->regs[4] = syscall_fn(regs->orig_a0, regs->regs[5], regs->regs[6],
 					   regs->regs[7], regs->regs[8], regs->regs[9]);
 	}
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index d0e1377..840d944 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -6,7 +6,12 @@
 
 #define PAGE_SIZE _PAGE_SIZE
 #define RO_EXCEPTION_TABLE_ALIGN	4
-#define PHYSADDR_MASK			0xffffffffffff /* 48-bit */
+
+#ifdef CONFIG_32BIT
+#define PHYSADDR_MASK			0x1fffffff	/* 29-bit */
+#else
+#define PHYSADDR_MASK			0xffffffffffff	/* 48-bit */
+#endif
 
 /*
  * Put .bss..swapper_pg_dir as the first thing in .bss. This will
diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig
index 8e52136..15da2d8 100644
--- a/arch/loongarch/kvm/Kconfig
+++ b/arch/loongarch/kvm/Kconfig
@@ -19,7 +19,7 @@
 
 config KVM
 	tristate "Kernel-based Virtual Machine (KVM) support"
-	depends on AS_HAS_LVZ_EXTENSION
+	depends on AS_HAS_LVZ_EXTENSION && 64BIT
 	select HAVE_KVM_DIRTY_RING_ACQ_REL
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_IRQCHIP
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index 827a885..aa21b381 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -3,8 +3,10 @@
 # Makefile for LoongArch-specific library files.
 #
 
-lib-y	+= delay.o memset.o memcpy.o memmove.o \
-	   clear_user.o copy_user.o csum.o dump_tlb.o unaligned.o
+lib-y	+= delay.o clear_user.o copy_user.o dump_tlb.o unaligned.o
+
+lib-$(CONFIG_32BIT) += bswapsi.o bswapdi.o
+lib-$(CONFIG_64BIT) += memset.o memcpy.o memmove.o csum.o
 
 obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
 
diff --git a/arch/loongarch/mm/Makefile b/arch/loongarch/mm/Makefile
index 278be2c..2aae377 100644
--- a/arch/loongarch/mm/Makefile
+++ b/arch/loongarch/mm/Makefile
@@ -7,6 +7,7 @@
 				   fault.o ioremap.o maccess.o mmap.o pgtable.o \
 				   page.o pageattr.o
 
+obj-$(CONFIG_HIGHMEM)		+= highmem.o
 obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 obj-$(CONFIG_KASAN)		+= kasan_init.o
 
diff --git a/arch/loongarch/mm/cache.c b/arch/loongarch/mm/cache.c
index 4969168..06dc570 100644
--- a/arch/loongarch/mm/cache.c
+++ b/arch/loongarch/mm/cache.c
@@ -31,16 +31,6 @@ void cache_error_setup(void)
 	set_merr_handler(0x0, &except_vec_cex, 0x80);
 }
 
-/*
- * LoongArch maintains ICache/DCache coherency by hardware,
- * we just need "ibar" to avoid instruction hazard here.
- */
-void local_flush_icache_range(unsigned long start, unsigned long end)
-{
-	asm volatile ("\tibar 0\n"::);
-}
-EXPORT_SYMBOL(local_flush_icache_range);
-
 static void flush_cache_leaf(unsigned int leaf)
 {
 	int i, j, nr_nodes;
diff --git a/arch/loongarch/mm/highmem.c b/arch/loongarch/mm/highmem.c
new file mode 100644
index 0000000..8a5789e
--- /dev/null
+++ b/arch/loongarch/mm/highmem.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/init.h>
+#include <linux/export.h>
+#include <linux/highmem.h>
+#include <asm/fixmap.h>
+#include <asm/tlbflush.h>
+
+void kmap_flush_tlb(unsigned long addr)
+{
+	flush_tlb_one(addr);
+}
+EXPORT_SYMBOL(kmap_flush_tlb);
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 00f3822b..3f9ab54 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -36,20 +36,6 @@
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 
-void copy_user_highpage(struct page *to, struct page *from,
-	unsigned long vaddr, struct vm_area_struct *vma)
-{
-	void *vfrom, *vto;
-
-	vfrom = kmap_local_page(from);
-	vto = kmap_local_page(to);
-	copy_page(vto, vfrom);
-	kunmap_local(vfrom);
-	kunmap_local(vto);
-	/* Make sure this page is cleared on other CPU's too before using it */
-	smp_wmb();
-}
-
 int __ref page_is_ram(unsigned long pfn)
 {
 	unsigned long addr = PFN_PHYS(pfn);
@@ -63,6 +49,9 @@ void __init arch_zone_limits_init(unsigned long *max_zone_pfns)
 	max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
 #endif
 	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
+#ifdef CONFIG_HIGHMEM
+	max_zone_pfns[ZONE_HIGHMEM] = max_pfn;
+#endif
 }
 
 void __ref free_initmem(void)
@@ -70,6 +59,50 @@ void __ref free_initmem(void)
 	free_initmem_default(POISON_FREE_INITMEM);
 }
 
+#ifdef CONFIG_HIGHMEM
+
+void __init fixrange_init(unsigned long start, unsigned long end, pgd_t *pgd_base)
+{
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j, k;
+	int ptrs_per_pgd;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = pgd_index(vaddr);
+	j = pud_index(vaddr);
+	k = pmd_index(vaddr);
+	pgd = pgd_base + i;
+	ptrs_per_pgd = min((1 << (BITS_PER_LONG - PGDIR_SHIFT)), PTRS_PER_PGD);
+
+	for ( ; (i < ptrs_per_pgd) && (vaddr < end); pgd++, i++) {
+		pud = (pud_t *)pgd;
+		for ( ; (j < PTRS_PER_PUD) && (vaddr < end); pud++, j++) {
+			pmd = (pmd_t *)pud;
+			for (; (k < PTRS_PER_PMD) && (vaddr < end); pmd++, k++) {
+				if (pmd_none(*pmd)) {
+					pte = (pte_t *) memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
+					if (!pte)
+						panic("%s: Failed to allocate %lu bytes align=%lx\n",
+						      __func__, PAGE_SIZE, PAGE_SIZE);
+
+					kernel_pte_init(pte);
+					set_pmd(pmd, __pmd((unsigned long)pte));
+					BUG_ON(pte != pte_offset_kernel(pmd, 0));
+				}
+				vaddr += PMD_SIZE;
+			}
+			k = 0;
+		}
+		j = 0;
+	}
+}
+
+#endif
+
 #ifdef CONFIG_MEMORY_HOTPLUG
 int arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params)
 {
diff --git a/arch/loongarch/mm/pgtable.c b/arch/loongarch/mm/pgtable.c
index 352d9b2..4ee188e 100644
--- a/arch/loongarch/mm/pgtable.c
+++ b/arch/loongarch/mm/pgtable.c
@@ -5,6 +5,7 @@
 #include <linux/init.h>
 #include <linux/export.h>
 #include <linux/mm.h>
+#include <asm/fixmap.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
@@ -144,6 +145,15 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
 
 void __init pagetable_init(void)
 {
+#ifdef CONFIG_HIGHMEM
+	unsigned long vaddr;
+	pgd_t *pgd;
+	p4d_t *p4d;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+#endif
+
 	/* Initialize the entire pgd.  */
 	pgd_init(swapper_pg_dir);
 	pgd_init(invalid_pg_dir);
@@ -153,4 +163,21 @@ void __init pagetable_init(void)
 #ifndef __PAGETABLE_PMD_FOLDED
 	pmd_init(invalid_pmd_table);
 #endif
+
+#ifdef CONFIG_HIGHMEM
+	/* Permanent kmaps */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr & PMD_MASK, vaddr + PAGE_SIZE * LAST_PKMAP, swapper_pg_dir);
+
+	pgd = swapper_pg_dir + pgd_index(vaddr);
+	p4d = p4d_offset(pgd, vaddr);
+	pud = pud_offset(p4d, vaddr);
+	pmd = pmd_offset(pud, vaddr);
+	pte = pte_offset_kernel(pmd, vaddr);
+	pkmap_page_table = pte;
+
+	/* Fixed mappings */
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1);
+	fixrange_init(vaddr & PMD_MASK, vaddr + FIXADDR_SIZE, swapper_pg_dir);
+#endif
 }
diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
index 5149ce4..24913dc 100644
--- a/arch/loongarch/net/bpf_jit.c
+++ b/arch/loongarch/net/bpf_jit.c
@@ -344,7 +344,13 @@ static int emit_bpf_tail_call(struct jit_ctx *ctx, int insn)
 #undef jmp_offset
 }
 
-static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
+static void emit_store_stack_imm64(struct jit_ctx *ctx, int reg, int stack_off, u64 imm64)
+{
+	move_imm(ctx, reg, imm64, false);
+	emit_insn(ctx, std, reg, LOONGARCH_GPR_FP, stack_off);
+}
+
+static int emit_atomic_rmw(const struct bpf_insn *insn, struct jit_ctx *ctx)
 {
 	const u8 t1 = LOONGARCH_GPR_T1;
 	const u8 t2 = LOONGARCH_GPR_T2;
@@ -363,10 +369,28 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
 	switch (imm) {
 	/* lock *(size *)(dst + off) <op>= src */
 	case BPF_ADD:
-		if (isdw)
-			emit_insn(ctx, amaddd, t2, t1, src);
-		else
+		switch (BPF_SIZE(insn->code)) {
+		case BPF_B:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amadd.b instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amaddb, t2, t1, src);
+			break;
+		case BPF_H:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amadd.h instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amaddh, t2, t1, src);
+			break;
+		case BPF_W:
 			emit_insn(ctx, amaddw, t2, t1, src);
+			break;
+		case BPF_DW:
+			emit_insn(ctx, amaddd, t2, t1, src);
+			break;
+		}
 		break;
 	case BPF_AND:
 		if (isdw)
@@ -388,11 +412,30 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
 		break;
 	/* src = atomic_fetch_<op>(dst + off, src) */
 	case BPF_ADD | BPF_FETCH:
-		if (isdw) {
-			emit_insn(ctx, amaddd, src, t1, t3);
-		} else {
+		switch (BPF_SIZE(insn->code)) {
+		case BPF_B:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amadd.b instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amaddb, src, t1, t3);
+			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_H:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amadd.h instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amaddh, src, t1, t3);
+			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_W:
 			emit_insn(ctx, amaddw, src, t1, t3);
 			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_DW:
+			emit_insn(ctx, amaddd, src, t1, t3);
+			break;
 		}
 		break;
 	case BPF_AND | BPF_FETCH:
@@ -421,11 +464,30 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
 		break;
 	/* src = atomic_xchg(dst + off, src); */
 	case BPF_XCHG:
-		if (isdw) {
-			emit_insn(ctx, amswapd, src, t1, t3);
-		} else {
+		switch (BPF_SIZE(insn->code)) {
+		case BPF_B:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amswap.b instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amswapb, src, t1, t3);
+			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_H:
+			if (!cpu_has_lam_bh) {
+				pr_err_once("bpf-jit: amswap.h instruction is not supported\n");
+				return -EINVAL;
+			}
+			emit_insn(ctx, amswaph, src, t1, t3);
+			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_W:
 			emit_insn(ctx, amswapw, src, t1, t3);
 			emit_zext_32(ctx, src, true);
+			break;
+		case BPF_DW:
+			emit_insn(ctx, amswapd, src, t1, t3);
+			break;
 		}
 		break;
 	/* r0 = atomic_cmpxchg(dst + off, r0, src); */
@@ -448,7 +510,105 @@ static void emit_atomic(const struct bpf_insn *insn, struct jit_ctx *ctx)
 			emit_zext_32(ctx, r0, true);
 		}
 		break;
+	default:
+		pr_err_once("bpf-jit: invalid atomic read-modify-write opcode %02x\n", imm);
+		return -EINVAL;
 	}
+
+	return 0;
+}
+
+static int emit_atomic_ld_st(const struct bpf_insn *insn, struct jit_ctx *ctx)
+{
+	const u8 t1 = LOONGARCH_GPR_T1;
+	const u8 src = regmap[insn->src_reg];
+	const u8 dst = regmap[insn->dst_reg];
+	const s16 off = insn->off;
+	const s32 imm = insn->imm;
+
+	switch (imm) {
+	/* dst_reg = load_acquire(src_reg + off16) */
+	case BPF_LOAD_ACQ:
+		switch (BPF_SIZE(insn->code)) {
+		case BPF_B:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, ldbu, dst, src, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, ldxbu, dst, src, t1);
+			}
+			break;
+		case BPF_H:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, ldhu, dst, src, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, ldxhu, dst, src, t1);
+			}
+			break;
+		case BPF_W:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, ldwu, dst, src, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, ldxwu, dst, src, t1);
+			}
+			break;
+		case BPF_DW:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, ldd, dst, src, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, ldxd, dst, src, t1);
+			}
+			break;
+		}
+		emit_insn(ctx, dbar, 0b10100);
+		break;
+	/* store_release(dst_reg + off16, src_reg) */
+	case BPF_STORE_REL:
+		emit_insn(ctx, dbar, 0b10010);
+		switch (BPF_SIZE(insn->code)) {
+		case BPF_B:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, stb, src, dst, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, stxb, src, dst, t1);
+			}
+			break;
+		case BPF_H:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, sth, src, dst, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, stxh, src, dst, t1);
+			}
+			break;
+		case BPF_W:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, stw, src, dst, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, stxw, src, dst, t1);
+			}
+			break;
+		case BPF_DW:
+			if (is_signed_imm12(off)) {
+				emit_insn(ctx, std, src, dst, off);
+			} else {
+				move_imm(ctx, t1, off, false);
+				emit_insn(ctx, stxd, src, dst, t1);
+			}
+			break;
+		}
+		break;
+	default:
+		pr_err_once("bpf-jit: invalid atomic load/store opcode %02x\n", imm);
+		return -EINVAL;
+	}
+
+	return 0;
 }
 
 static bool is_signed_bpf_cond(u8 cond)
@@ -1254,9 +1414,17 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
 			return ret;
 		break;
 
+	/* Atomics */
+	case BPF_STX | BPF_ATOMIC | BPF_B:
+	case BPF_STX | BPF_ATOMIC | BPF_H:
 	case BPF_STX | BPF_ATOMIC | BPF_W:
 	case BPF_STX | BPF_ATOMIC | BPF_DW:
-		emit_atomic(insn, ctx);
+		if (!bpf_atomic_is_load_store(insn))
+			ret = emit_atomic_rmw(insn, ctx);
+		else
+			ret = emit_atomic_ld_st(insn, ctx);
+		if (ret)
+			return ret;
 		break;
 
 	/* Speculation barrier */
@@ -1466,26 +1634,46 @@ int bpf_arch_text_invalidate(void *dst, size_t len)
 	return ret;
 }
 
-static void store_args(struct jit_ctx *ctx, int nargs, int args_off)
+static void store_args(struct jit_ctx *ctx, int nr_arg_slots, int args_off)
 {
 	int i;
 
-	for (i = 0; i < nargs; i++) {
-		emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
+	for (i = 0; i < nr_arg_slots; i++) {
+		if (i < LOONGARCH_MAX_REG_ARGS)
+			emit_insn(ctx, std, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
+		else {
+			/* Skip slots for T0 and FP of traced function */
+			emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
+				  16 + (i - LOONGARCH_MAX_REG_ARGS) * 8);
+			emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -args_off);
+		}
 		args_off -= 8;
 	}
 }
 
-static void restore_args(struct jit_ctx *ctx, int nargs, int args_off)
+static void restore_args(struct jit_ctx *ctx, int nr_reg_args, int args_off)
 {
 	int i;
 
-	for (i = 0; i < nargs; i++) {
+	for (i = 0; i < nr_reg_args; i++) {
 		emit_insn(ctx, ldd, LOONGARCH_GPR_A0 + i, LOONGARCH_GPR_FP, -args_off);
 		args_off -= 8;
 	}
 }
 
+static void restore_stk_args(struct jit_ctx *ctx, int nr_stk_args, int args_off, int stk_args_off)
+{
+	int i;
+
+	for (i = 0; i < nr_stk_args; i++) {
+		emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP,
+			  -(args_off - LOONGARCH_MAX_REG_ARGS * 8));
+		emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -stk_args_off);
+		args_off -= 8;
+		stk_args_off -= 8;
+	}
+}
+
 static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
 			   int args_off, int retval_off, int run_ctx_off, bool save_ret)
 {
@@ -1494,12 +1682,11 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
 	struct bpf_prog *p = l->link.prog;
 	int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie);
 
-	if (l->cookie) {
-		move_imm(ctx, LOONGARCH_GPR_T1, l->cookie, false);
-		emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off);
-	} else {
+	if (l->cookie)
+		emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1,
+				      -run_ctx_off + cookie_off, l->cookie);
+	else
 		emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -run_ctx_off + cookie_off);
-	}
 
 	/* arg1: prog */
 	move_imm(ctx, LOONGARCH_GPR_A0, (const s64)p, false);
@@ -1550,18 +1737,27 @@ static int invoke_bpf_prog(struct jit_ctx *ctx, struct bpf_tramp_link *l,
 	return ret;
 }
 
-static void invoke_bpf_mod_ret(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
-			       int args_off, int retval_off, int run_ctx_off, u32 **branches)
+static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
+		      int args_off, int retval_off, int run_ctx_off,
+		      int func_meta_off, bool save_ret, u64 func_meta, int cookie_off)
 {
-	int i;
+	int i, cur_cookie = (cookie_off - args_off) / 8;
 
-	emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
 	for (i = 0; i < tl->nr_links; i++) {
-		invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, true);
-		emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off);
-		branches[i] = (u32 *)ctx->image + ctx->idx;
-		emit_insn(ctx, nop);
+		int err;
+
+		if (bpf_prog_calls_session_cookie(tl->links[i])) {
+			u64 meta = func_meta | ((u64)cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT);
+
+			emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, meta);
+			cur_cookie--;
+		}
+		err = invoke_bpf_prog(ctx, tl->links[i], args_off, retval_off, run_ctx_off, save_ret);
+		if (err)
+			return err;
 	}
+
+	return 0;
 }
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
@@ -1615,8 +1811,10 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 					 void *func_addr, u32 flags)
 {
 	int i, ret, save_ret;
-	int stack_size, nargs;
-	int retval_off, args_off, nargs_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
+	int cookie_cnt, cookie_off;
+	int stack_size, args_off, stk_args_off, nr_arg_slots = 0;
+	int retval_off, func_meta_off, ip_off, run_ctx_off, sreg_off, tcc_ptr_off;
+	unsigned long long func_meta;
 	bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT;
 	void *orig_call = func_addr;
 	struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
@@ -1634,30 +1832,44 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	 * FP - 16      [ FP of traced func ] frame pointer of traced
 	 *                    function
 	 *
-	 * FP - retval_off  [ return value      ] BPF_TRAMP_F_CALL_ORIG or
-	 *                    BPF_TRAMP_F_RET_FENTRY_RET
-	 *                  [ argN              ]
-	 *                  [ ...               ]
-	 * FP - args_off    [ arg1              ]
+	 * FP - retval_off   [ return value      ] BPF_TRAMP_F_CALL_ORIG or
+	 *                                         BPF_TRAMP_F_RET_FENTRY_RET
+	 *                   [ arg regN          ]
+	 *                   [ ...               ]
+	 * FP - args_off     [ arg reg1          ]
 	 *
-	 * FP - nargs_off   [ regs count        ]
+	 * FP - func_meta_off [ regs count, etc ]
 	 *
-	 * FP - ip_off      [ traced func   ] BPF_TRAMP_F_IP_ARG
+	 * FP - ip_off       [ traced func       ] BPF_TRAMP_F_IP_ARG
 	 *
-	 * FP - run_ctx_off [ bpf_tramp_run_ctx ]
+	 *                   [ stack cookie N    ]
+	 *                   [ ...               ]
+	 * FP - cookie_off   [ stack cookie 1    ]
 	 *
-	 * FP - sreg_off    [ callee saved reg  ]
+	 * FP - run_ctx_off  [ bpf_tramp_run_ctx ]
 	 *
-	 * FP - tcc_ptr_off [ tail_call_cnt_ptr ]
+	 * FP - sreg_off     [ callee saved reg  ]
+	 *
+	 * FP - tcc_ptr_off  [ tail_call_cnt_ptr ]
+	 *
+	 *                   [ stack_argN        ]
+	 *                   [ ...               ]
+	 * FP - stk_args_off [ stack_arg1        ] BPF_TRAMP_F_CALL_ORIG
 	 */
 
-	if (m->nr_args > LOONGARCH_MAX_REG_ARGS)
+	if (m->nr_args > MAX_BPF_FUNC_ARGS)
 		return -ENOTSUPP;
 
-	/* FIXME: No support of struct argument */
+	/* Extra registers for struct arguments */
 	for (i = 0; i < m->nr_args; i++) {
-		if (m->arg_flags[i] & BTF_FMODEL_STRUCT_ARG)
-			return -ENOTSUPP;
+		/*
+		 * The struct argument size is at most 16 bytes,
+		 * enforced by the verifier. The struct argument
+		 * may be passed in a pair of registers if its
+		 * size is more than 8 bytes and no more than 16
+		 * bytes.
+		 */
+		nr_arg_slots += round_up(m->arg_size[i], 8) / 8;
 	}
 
 	if (flags & (BPF_TRAMP_F_ORIG_STACK | BPF_TRAMP_F_SHARE_IPMODIFY))
@@ -1673,13 +1885,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	retval_off = stack_size;
 
 	/* Room of trampoline frame to store args */
-	nargs = m->nr_args;
-	stack_size += nargs * 8;
+	stack_size += nr_arg_slots * 8;
 	args_off = stack_size;
 
-	/* Room of trampoline frame to store args number */
+	/* Room of function metadata, such as regs count */
 	stack_size += 8;
-	nargs_off = stack_size;
+	func_meta_off = stack_size;
 
 	/* Room of trampoline frame to store ip address */
 	if (flags & BPF_TRAMP_F_IP_ARG) {
@@ -1687,6 +1898,12 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 		ip_off = stack_size;
 	}
 
+	cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
+
+	/* Room for session cookies */
+	stack_size += cookie_cnt * 8;
+	cookie_off = stack_size;
+
 	/* Room of trampoline frame to store struct bpf_tramp_run_ctx */
 	stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8);
 	run_ctx_off = stack_size;
@@ -1700,8 +1917,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 		tcc_ptr_off = stack_size;
 	}
 
+	if ((flags & BPF_TRAMP_F_CALL_ORIG) && (nr_arg_slots - LOONGARCH_MAX_REG_ARGS > 0))
+		stack_size += (nr_arg_slots - LOONGARCH_MAX_REG_ARGS) * 8;
+
 	stack_size = round_up(stack_size, 16);
 
+	/* Room for args on stack must be at the top of stack */
+	stk_args_off = stack_size;
+
 	if (is_struct_ops) {
 		/*
 		 * For the trampoline called directly, just handle
@@ -1737,17 +1960,24 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	emit_insn(ctx, std, LOONGARCH_GPR_S1, LOONGARCH_GPR_FP, -sreg_off);
 
 	/* store ip address of the traced function */
-	if (flags & BPF_TRAMP_F_IP_ARG) {
-		move_imm(ctx, LOONGARCH_GPR_T1, (const s64)func_addr, false);
-		emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -ip_off);
+	if (flags & BPF_TRAMP_F_IP_ARG)
+		emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -ip_off, (u64)func_addr);
+
+	/* store arg regs count */
+	func_meta = nr_arg_slots;
+	emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
+
+	store_args(ctx, nr_arg_slots, args_off);
+
+	if (bpf_fsession_cnt(tlinks)) {
+		/* clear all session cookies' value */
+		for (i = 0; i < cookie_cnt; i++)
+			emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -cookie_off + 8 * i);
+
+		/* clear return value to make sure fentry always get 0 */
+		emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
 	}
 
-	/* store nargs number */
-	move_imm(ctx, LOONGARCH_GPR_T1, nargs, false);
-	emit_insn(ctx, std, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -nargs_off);
-
-	store_args(ctx, nargs, args_off);
-
 	/* To traced function */
 	/* Ftrace jump skips 2 NOP instructions */
 	if (is_kernel_text((unsigned long)orig_call) ||
@@ -1764,9 +1994,9 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 			return ret;
 	}
 
-	for (i = 0; i < fentry->nr_links; i++) {
-		ret = invoke_bpf_prog(ctx, fentry->links[i], args_off, retval_off,
-				      run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET);
+	if (fentry->nr_links) {
+		ret = invoke_bpf(ctx, fentry, args_off, retval_off, run_ctx_off, func_meta_off,
+				 flags & BPF_TRAMP_F_RET_FENTRY_RET, func_meta, cookie_off);
 		if (ret)
 			return ret;
 	}
@@ -1775,11 +2005,21 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 		if (!branches)
 			return -ENOMEM;
 
-		invoke_bpf_mod_ret(ctx, fmod_ret, args_off, retval_off, run_ctx_off, branches);
+		emit_insn(ctx, std, LOONGARCH_GPR_ZERO, LOONGARCH_GPR_FP, -retval_off);
+		for (i = 0; i < fmod_ret->nr_links; i++) {
+			ret = invoke_bpf_prog(ctx, fmod_ret->links[i],
+					      args_off, retval_off, run_ctx_off, true);
+			if (ret)
+				goto out;
+			emit_insn(ctx, ldd, LOONGARCH_GPR_T1, LOONGARCH_GPR_FP, -retval_off);
+			branches[i] = (u32 *)ctx->image + ctx->idx;
+			emit_insn(ctx, nop);
+		}
 	}
 
 	if (flags & BPF_TRAMP_F_CALL_ORIG) {
-		restore_args(ctx, m->nr_args, args_off);
+		restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args_off);
+		restore_stk_args(ctx, nr_arg_slots - LOONGARCH_MAX_REG_ARGS, args_off, stk_args_off);
 
 		if (flags & BPF_TRAMP_F_TAIL_CALL_CTX)
 			emit_insn(ctx, ldd, REG_TCC, LOONGARCH_GPR_FP, -tcc_ptr_off);
@@ -1800,8 +2040,14 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 		*branches[i] = larch_insn_gen_bne(LOONGARCH_GPR_T1, LOONGARCH_GPR_ZERO, offset);
 	}
 
-	for (i = 0; i < fexit->nr_links; i++) {
-		ret = invoke_bpf_prog(ctx, fexit->links[i], args_off, retval_off, run_ctx_off, false);
+	/* Set "is_return" flag for fsession */
+	func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
+	if (bpf_fsession_cnt(tlinks))
+		emit_store_stack_imm64(ctx, LOONGARCH_GPR_T1, -func_meta_off, func_meta);
+
+	if (fexit->nr_links) {
+		ret = invoke_bpf(ctx, fexit, args_off, retval_off, run_ctx_off,
+				 func_meta_off, false, func_meta, cookie_off);
 		if (ret)
 			goto out;
 	}
@@ -1815,7 +2061,7 @@ static int __arch_prepare_bpf_trampoline(struct jit_ctx *ctx, struct bpf_tramp_i
 	}
 
 	if (flags & BPF_TRAMP_F_RESTORE_REGS)
-		restore_args(ctx, m->nr_args, args_off);
+		restore_args(ctx, min_t(int, nr_arg_slots, LOONGARCH_MAX_REG_ARGS), args_off);
 
 	if (save_ret) {
 		emit_insn(ctx, ldd, regmap[BPF_REG_0], LOONGARCH_GPR_FP, -(retval_off - 8));
@@ -2111,6 +2357,11 @@ bool bpf_jit_supports_arena(void)
 	return true;
 }
 
+bool bpf_jit_supports_fsession(void)
+{
+	return true;
+}
+
 /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */
 bool bpf_jit_supports_subprog_tailcalls(void)
 {
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig
index d10b3d4..acbab8d 100644
--- a/arch/mips/configs/bcm47xx_defconfig
+++ b/arch/mips/configs/bcm47xx_defconfig
@@ -28,7 +28,6 @@
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
 CONFIG_NET_SCH_FQ_CODEL=y
-CONFIG_HAMRADIO=y
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_MTD=y
diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig
index 3b64e15..aa63ada 100644
--- a/arch/mips/configs/bigsur_defconfig
+++ b/arch/mips/configs/bigsur_defconfig
@@ -84,16 +84,6 @@
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
 CONFIG_VLAN_8021Q_GVRP=y
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_FW_LOADER=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_NBD=m
diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig
index 281dd7d..49fe970 100644
--- a/arch/mips/configs/db1xxx_defconfig
+++ b/arch/mips/configs/db1xxx_defconfig
@@ -105,7 +105,6 @@
 CONFIG_PATA_PLATFORM=y
 CONFIG_NETDEVICES=y
 CONFIG_NLMON=y
-CONFIG_PCMCIA_3C589=y
 CONFIG_MIPS_AU1X00_ENET=y
 CONFIG_SMC91X=y
 CONFIG_SMSC911X=y
diff --git a/arch/mips/configs/gpr_defconfig b/arch/mips/configs/gpr_defconfig
index fdd28a8..ed1a8f8 100644
--- a/arch/mips/configs/gpr_defconfig
+++ b/arch/mips/configs/gpr_defconfig
@@ -87,9 +87,6 @@
 CONFIG_IP_SCTP=m
 CONFIG_TIPC=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
@@ -104,7 +101,6 @@
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
 CONFIG_NET_SCH_PRIO=m
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
@@ -130,17 +126,6 @@
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_PKTGEN=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-# CONFIG_AX25_DAMA_SLAVE is not set
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
 CONFIG_MTD=y
@@ -167,15 +152,6 @@
 CONFIG_NETDEVICES=y
 CONFIG_NET_FC=y
 CONFIG_NETCONSOLE=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_IA=m
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
 CONFIG_MIPS_AU1X00_ENET=y
 CONFIG_CICADA_PHY=m
 CONFIG_DAVICOM_PHY=m
diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig
index 72568f8..3629afb 100644
--- a/arch/mips/configs/mtx1_defconfig
+++ b/arch/mips/configs/mtx1_defconfig
@@ -15,7 +15,6 @@
 CONFIG_PCCARD=m
 CONFIG_YENTA=m
 CONFIG_PD6729=m
-CONFIG_I82092=m
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
@@ -133,9 +132,6 @@
 CONFIG_IP_SCTP=m
 CONFIG_TIPC=m
 CONFIG_ATM=y
-CONFIG_ATM_CLIP=y
-CONFIG_ATM_LANE=m
-CONFIG_ATM_MPOA=m
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
@@ -150,7 +146,6 @@
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
 CONFIG_NET_SCH_PRIO=m
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
@@ -176,17 +171,6 @@
 CONFIG_NET_CLS_ACT=y
 CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_PKTGEN=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-# CONFIG_AX25_DAMA_SLAVE is not set
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
-CONFIG_BAYCOM_SER_FDX=m
-CONFIG_BAYCOM_SER_HDX=m
-CONFIG_YAM=m
 CONFIG_BT=m
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
@@ -243,23 +227,11 @@
 CONFIG_ARCNET_COM20020=m
 CONFIG_ARCNET_COM20020_PCI=m
 CONFIG_ARCNET_COM20020_CS=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_IA=m
-CONFIG_ATM_FORE200E=m
-CONFIG_ATM_HE=m
-CONFIG_ATM_HE_USE_SUNI=y
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_3C589=m
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_AMD8111_ETH=m
 CONFIG_PCNET32=m
-CONFIG_PCMCIA_NMCLAN=m
 CONFIG_B44=m
 CONFIG_BNX2=m
 CONFIG_TIGON3=m
@@ -273,7 +245,6 @@
 CONFIG_PCMCIA_XIRCOM=m
 CONFIG_DL2K=m
 CONFIG_SUNDANCE=m
-CONFIG_PCMCIA_FMVJ18X=m
 CONFIG_E100=m
 CONFIG_E1000=m
 CONFIG_SKGE=m
@@ -282,12 +253,9 @@
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NS83820=m
-CONFIG_PCMCIA_AXNET=m
 CONFIG_NE2K_PCI=m
 CONFIG_PCMCIA_PCNET=m
 CONFIG_FORCEDETH=m
-CONFIG_HAMACHI=m
-CONFIG_YELLOWFIN=m
 CONFIG_QLA3XXX=m
 CONFIG_8139CP=m
 CONFIG_8139TOO=m
@@ -296,7 +264,6 @@
 CONFIG_R8169=m
 CONFIG_SIS900=m
 CONFIG_SIS190=m
-CONFIG_PCMCIA_SMC91C92=m
 CONFIG_EPIC100=m
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNGEM=m
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig
index 30d18b0..a88322f 100644
--- a/arch/mips/configs/rb532_defconfig
+++ b/arch/mips/configs/rb532_defconfig
@@ -95,7 +95,6 @@
 CONFIG_GACT_PROB=y
 CONFIG_NET_ACT_MIRRED=m
 CONFIG_NET_ACT_PEDIT=m
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_BLOCK2MTD=y
diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig
index b1e67ff..ad9fbd0 100644
--- a/arch/mips/configs/rm200_defconfig
+++ b/arch/mips/configs/rm200_defconfig
@@ -147,13 +147,6 @@
 CONFIG_NET_CLS_U32=m
 CONFIG_NET_CLS_RSVP=m
 CONFIG_NET_CLS_RSVP6=m
-CONFIG_HAMRADIO=y
-CONFIG_AX25=m
-CONFIG_NETROM=m
-CONFIG_ROSE=m
-CONFIG_MKISS=m
-CONFIG_6PACK=m
-CONFIG_BPQETHER=m
 CONFIG_CONNECTOR=m
 CONFIG_PARPORT=m
 CONFIG_PARPORT_PC=m
diff --git a/arch/mips/configs/rt305x_defconfig b/arch/mips/configs/rt305x_defconfig
index 8f9701e..c920976 100644
--- a/arch/mips/configs/rt305x_defconfig
+++ b/arch/mips/configs/rt305x_defconfig
@@ -64,7 +64,6 @@
 # CONFIG_BRIDGE_IGMP_SNOOPING is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig
index aae8497..f1c53bb 100644
--- a/arch/mips/configs/xway_defconfig
+++ b/arch/mips/configs/xway_defconfig
@@ -66,7 +66,6 @@
 # CONFIG_BRIDGE_IGMP_SNOOPING is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_SCHED=y
-CONFIG_HAMRADIO=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 62d5a89..d3afac2f 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -8,6 +8,7 @@
 	select HAVE_FUNCTION_GRAPH_TRACER
 	select HAVE_SYSCALL_TRACEPOINTS
 	select ARCH_WANT_FRAME_POINTERS
+	select ARCH_WANTS_MODULES_TEXT_SECTIONS if !64BIT
 	select ARCH_HAS_CPU_CACHE_ALIASING
 	select ARCH_HAS_DMA_ALLOC if PA11
 	select ARCH_HAS_DMA_OPS
@@ -130,6 +131,9 @@
 config GENERIC_BUG_RELATIVE_POINTERS
 	bool
 
+config GENERIC_CSUM
+	def_bool y
+
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -354,7 +358,8 @@
 source "kernel/Kconfig.hz"
 
 config COMPAT
-	def_bool y
+	bool "Kernel support for 32-bit binaries"
+	default 64BIT
 	depends on 64BIT
 
 config AUDIT_ARCH
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 48ae3c7..edab2a9 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -176,10 +176,12 @@
 vdso_prepare: prepare0
 	$(if $(CONFIG_64BIT),$(Q)$(MAKE) \
 		$(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h)
-	$(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h
+	$(if $(CONFIG_PA11)$(CONFIG_COMPAT),$(Q)$(MAKE) \
+		$(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h)
 endif
 
-vdso-install-y			+= arch/parisc/kernel/vdso32/vdso32.so
+vdso-install-$(CONFIG_PA11)	+= arch/parisc/kernel/vdso32/vdso32.so
+vdso-install-$(CONFIG_COMPAT)	+= arch/parisc/kernel/vdso32/vdso32.so
 vdso-install-$(CONFIG_64BIT)	+= arch/parisc/kernel/vdso64/vdso64.so
 
 install: KBUILD_IMAGE := vmlinux
diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h
index 2aceebc..3827588 100644
--- a/arch/parisc/include/asm/checksum.h
+++ b/arch/parisc/include/asm/checksum.h
@@ -4,73 +4,7 @@
 
 #include <linux/in6.h>
 
-/*
- * computes the checksum of a memory block at buff, length len,
- * and adds in "sum" (32-bit)
- *
- * returns a 32-bit number suitable for feeding into itself
- * or csum_tcpudp_magic
- *
- * this function must be called with even lengths, except
- * for the last fragment, which may be odd
- *
- * it's best to have buff aligned on a 32-bit boundary
- */
-extern __wsum csum_partial(const void *, int, __wsum);
-
-/*
- *	Optimized for IP headers, which always checksum on 4 octet boundaries.
- *
- *	Written by Randolph Chung <tausq@debian.org>, and then mucked with by
- *	LaMont Jones <lamont@debian.org>
- */
-static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
-{
-	unsigned int sum;
-	unsigned long t0, t1, t2;
-
-	__asm__ __volatile__ (
-"	ldws,ma		4(%1), %0\n"
-"	addib,<=	-4, %2, 2f\n"
-"\n"
-"	ldws		4(%1), %4\n"
-"	ldws		8(%1), %5\n"
-"	add		%0, %4, %0\n"
-"	ldws,ma		12(%1), %3\n"
-"	addc		%0, %5, %0\n"
-"	addc		%0, %3, %0\n"
-"1:	ldws,ma		4(%1), %3\n"
-"	addib,>		-1, %2, 1b\n"
-"	addc		%0, %3, %0\n"
-"\n"
-"	extru		%0, 31, 16, %4\n"
-"	extru		%0, 15, 16, %5\n"
-"	addc		%4, %5, %0\n"
-"	extru		%0, 15, 16, %5\n"
-"	add		%0, %5, %0\n"
-"	subi		-1, %0, %0\n"
-"2:\n"
-	: "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2)
-	: "1" (iph), "2" (ihl)
-	: "memory");
-
-	return (__force __sum16)sum;
-}
-
-/*
- *	Fold a partial checksum
- */
-static inline __sum16 csum_fold(__wsum csum)
-{
-	u32 sum = (__force u32)csum;
-	/* add the swapped two 16-bit halves of sum,
-	   a possible carry from adding the two 16-bit halves,
-	   will carry from the lower half into the upper half,
-	   giving us the correct sum in the upper half. */
-	sum += (sum << 16) + (sum >> 16);
-	return (__force __sum16)(~sum >> 16);
-}
- 
+#define csum_tcpudp_nofold csum_tcpudp_nofold
 static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 					__u32 len, __u8 proto,
 					__wsum sum)
@@ -85,26 +19,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
 	return sum;
 }
 
-/*
- * computes the checksum of the TCP/UDP pseudo-header
- * returns a 16-bit checksum, already complemented
- */
-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
-					__u32 len, __u8 proto,
-					__wsum sum)
-{
-	return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
-}
-
-/*
- * this routine is used for miscellaneous IP-like checksums, mainly
- * in icmp.c
- */
-static inline __sum16 ip_compute_csum(const void *buf, int len)
-{
-	 return csum_fold (csum_partial(buf, len, 0));
-}
-
+#include <asm-generic/checksum.h>
 
 #define _HAVE_ARCH_IPV6_CSUM
 static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index 339d1b8..13a5a55 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h
@@ -130,7 +130,7 @@ typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
 
 static inline int __is_compat_task(struct task_struct *t)
 {
-	return test_tsk_thread_flag(t, TIF_32BIT);
+	return IS_ENABLED(CONFIG_COMPAT) && test_tsk_thread_flag(t, TIF_32BIT);
 }
 
 static inline int is_compat_task(void)
diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h
index 81bc1d4..5501560 100644
--- a/arch/parisc/include/asm/vdso.h
+++ b/arch/parisc/include/asm/vdso.h
@@ -7,7 +7,9 @@
 #ifdef CONFIG_64BIT
 #include <generated/vdso64-offsets.h>
 #endif
+#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
 #include <generated/vdso32-offsets.h>
+#endif
 
 #define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
 #define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name))
diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile
index 9157bc8..2f34417 100644
--- a/arch/parisc/kernel/Makefile
+++ b/arch/parisc/kernel/Makefile
@@ -47,4 +47,5 @@
 # vdso
 obj-y			+= vdso.o
 obj-$(CONFIG_64BIT)	+= vdso64/
-obj-y			+= vdso32/
+obj-$(CONFIG_PA11)	+= vdso32/
+obj-$(CONFIG_COMPAT)	+= vdso32/
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index e8d27de..64a6200 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -80,7 +80,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	sigset_t set;
 	unsigned long usp = (regs->gr[30] & ~(0x01UL));
 	unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	struct compat_rt_sigframe __user * compat_frame;
 	
 	if (is_compat_task())
@@ -96,7 +96,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 
 	regs->orig_r28 = 1; /* no restarts for sigreturn */
 
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	compat_frame = (struct compat_rt_sigframe __user *)frame;
 	
 	if (is_compat_task()) {
@@ -112,7 +112,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 	set_current_blocked(&set);
 
 	/* Good thing we saved the old gr[30], eh? */
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	if (is_compat_task()) {
 		DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n",
 				__func__, &compat_frame->uc.uc_mcontext);
@@ -218,13 +218,13 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 	unsigned long haddr, sigframe_size;
 	unsigned long start;
 	int err = 0;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	struct compat_rt_sigframe __user * compat_frame;
 #endif
-	
+
 	usp = (regs->gr[30] & ~(0x01UL));
 	sigframe_size = PARISC_RT_SIGFRAME_SIZE;
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	if (is_compat_task()) {
 		/* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
 		usp = (compat_uint_t)usp;
@@ -239,7 +239,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 	if (start >= TASK_SIZE_MAX - sigframe_size)
 		return -EFAULT;
 	
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 
 	compat_frame = (struct compat_rt_sigframe __user *)frame;
 	
@@ -349,8 +349,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 
 	regs->gr[2]  = rp;			/* userland return pointer */
 	regs->gr[26] = ksig->sig;               /* signal number */
-	
-#ifdef CONFIG_64BIT
+
+#ifdef CONFIG_COMPAT
 	if (is_compat_task()) {
 		regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 		regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index fcb0d80..1a676a9 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -50,9 +50,13 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr,
 }
 
 
+#ifdef CONFIG_COMPAT
 #define STACK_SIZE_DEFAULT (USER_WIDE_MODE			\
 			? (1 << 30)	/* 1 GB */		\
 			: (CONFIG_STACK_MAX_DEFAULT_SIZE_MB*1024*1024))
+#else
+#define STACK_SIZE_DEFAULT (1 << 30)
+#endif
 
 unsigned long calc_max_stack_size(unsigned long stack_max)
 {
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
index f58c4bcc..e11c88c 100644
--- a/arch/parisc/kernel/syscall.S
+++ b/arch/parisc/kernel/syscall.S
@@ -241,7 +241,7 @@
 	/* Note!  We cannot use the syscall table that is mapped
 	nearby since the gateway page is mapped execute-only. */
 
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	ldil	L%sys_call_table, %r1
 	or,ev	%r2,%r2,%r2
 	ldil	L%sys_call_table64, %r1
@@ -250,7 +250,7 @@
 	ldo	R%sys_call_table64(%r1), %r19
 #else
 	load32	sys_call_table, %r19
-#endif	
+#endif
 	comiclr,>>	__NR_Linux_syscalls, %r20, %r0
 	b,n	.Lsyscall_nosys
 	
@@ -374,7 +374,7 @@
 	/* Note!  We cannot use the syscall table that is mapped
 	nearby since the gateway page is mapped execute-only. */
 
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 	LDREG	TASK_PT_GR30(%r1), %r19		/* get users sp back */
 	extrd,u	%r19,63,1,%r2			/* W hidden in bottom bit */
 
@@ -1326,16 +1326,19 @@
 END(lws_table)
 	/* End of lws table */
 
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_COMPAT
 #define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, compat)
 #else
 #define __SYSCALL_WITH_COMPAT(nr, native, compat)	__SYSCALL(nr, native)
 #endif
 #define __SYSCALL(nr, entry)	ASM_ULONG_INSN entry
+
 	.align 8
 ENTRY(sys_call_table)
 	.export sys_call_table,data
+#if defined(CONFIG_COMPAT) || !defined(CONFIG_64BIT)
 #include <asm/syscall_table_32.h>    /* 32-bit syscalls */
+#endif
 END(sys_call_table)
 
 #ifdef CONFIG_64BIT
diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl
index f6e2d03..c6331da 100644
--- a/arch/parisc/kernel/syscalls/syscall.tbl
+++ b/arch/parisc/kernel/syscalls/syscall.tbl
@@ -154,7 +154,7 @@
 # 137 was afs_syscall
 138	common	setfsuid		sys_setfsuid
 139	common	setfsgid		sys_setfsgid
-140	common	_llseek			sys_llseek
+140	32	_llseek			sys_llseek
 141	common	getdents		sys_getdents			compat_sys_getdents
 142	common	_newselect		sys_select			compat_sys_select
 143	common	flock			sys_flock
diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile
index 7b19766..d5975d1 100644
--- a/arch/parisc/lib/Makefile
+++ b/arch/parisc/lib/Makefile
@@ -3,7 +3,7 @@
 # Makefile for parisc-specific library files
 #
 
-lib-y	:= lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \
+lib-y	:= lusercopy.o bitops.o io.o memset.o memcpy.o \
 	   ucmpdi2.o delay.o
 
 obj-y	:= iomap.o
diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c
deleted file mode 100644
index 59d8c15..0000000
--- a/arch/parisc/lib/checksum.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		MIPS specific IP/TCP/UDP checksumming routines
- *
- * Authors:	Ralf Baechle, <ralf@waldorf-gmbh.de>
- *		Lots of code moved from tcp.c and ip.c; see those files
- *		for more names.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-
-#include <net/checksum.h>
-#include <asm/byteorder.h>
-#include <asm/string.h>
-#include <linux/uaccess.h>
-
-#define addc(_t,_r)                     \
-	__asm__ __volatile__ (          \
-"       add             %0, %1, %0\n"   \
-"       addc            %0, %%r0, %0\n" \
-	: "=r"(_t)                      \
-	: "r"(_r), "0"(_t));
-
-static inline unsigned int do_csum(const unsigned char * buff, int len)
-{
-	int odd, count;
-	unsigned int result = 0;
-
-	if (len <= 0)
-		goto out;
-	odd = 1 & (unsigned long) buff;
-	if (odd) {
-		result = be16_to_cpu(*buff);
-		len--;
-		buff++;
-	}
-	count = len >> 1;		/* nr of 16-bit words.. */
-	if (count) {
-		if (2 & (unsigned long) buff) {
-			result += *(unsigned short *) buff;
-			count--;
-			len -= 2;
-			buff += 2;
-		}
-		count >>= 1;		/* nr of 32-bit words.. */
-		if (count) {
-			while (count >= 4) {
-				unsigned int r1, r2, r3, r4;
-				r1 = *(unsigned int *)(buff + 0);
-				r2 = *(unsigned int *)(buff + 4);
-				r3 = *(unsigned int *)(buff + 8);
-				r4 = *(unsigned int *)(buff + 12);
-				addc(result, r1);
-				addc(result, r2);
-				addc(result, r3);
-				addc(result, r4);
-				count -= 4;
-				buff += 16;
-			}
-			while (count) {
-				unsigned int w = *(unsigned int *) buff;
-				count--;
-				buff += 4;
-				addc(result, w);
-			}
-			result = (result & 0xffff) + (result >> 16);
-		}
-		if (len & 2) {
-			result += *(unsigned short *) buff;
-			buff += 2;
-		}
-	}
-	if (len & 1)
-		result += le16_to_cpu(*buff);
-	result = csum_from32to16(result);
-	if (odd)
-		result = swab16(result);
-out:
-	return result;
-}
-
-/*
- * computes a partial checksum, e.g. for TCP/UDP fragments
- */
-/*
- * why bother folding?
- */
-__wsum csum_partial(const void *buff, int len, __wsum sum)
-{
-	unsigned int result = do_csum(buff, len);
-	addc(result, sum);
-	return (__force __wsum)csum_from32to16(result);
-}
-
-EXPORT_SYMBOL(csum_partial);
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 6f40a27..ccabc6e 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -72,8 +72,6 @@
 CONFIG_PCCARD=y
 CONFIG_YENTA=y
 CONFIG_PD6729=m
-CONFIG_I82092=m
-CONFIG_I82365=m
 CONFIG_ADVANCED_OPTIONS=y
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -227,8 +225,6 @@
 CONFIG_BRIDGE_EBT_NFLOG=m
 CONFIG_TIPC=m
 CONFIG_ATM=m
-CONFIG_ATM_CLIP=m
-CONFIG_ATM_LANE=m
 CONFIG_ATM_BR2684=m
 CONFIG_BRIDGE=m
 CONFIG_VLAN_8021Q=m
@@ -240,7 +236,6 @@
 CONFIG_NET_SCH_CBQ=m
 CONFIG_NET_SCH_HTB=m
 CONFIG_NET_SCH_HFSC=m
-CONFIG_NET_SCH_ATM=m
 CONFIG_NET_SCH_PRIO=m
 CONFIG_NET_SCH_MULTIQ=m
 CONFIG_NET_SCH_RED=m
@@ -398,21 +393,11 @@
 CONFIG_TUN=m
 CONFIG_VETH=m
 CONFIG_VIRTIO_NET=m
-CONFIG_ATM_TCP=m
-CONFIG_ATM_LANAI=m
-CONFIG_ATM_ENI=m
-CONFIG_ATM_NICSTAR=m
-CONFIG_ATM_IDT77252=m
-CONFIG_ATM_HE=m
-CONFIG_EL3=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_3C589=m
 CONFIG_VORTEX=m
 CONFIG_TYPHOON=m
 CONFIG_ADAPTEC_STARFIRE=m
 CONFIG_AMD8111_ETH=m
 CONFIG_PCNET32=m
-CONFIG_PCMCIA_NMCLAN=m
 CONFIG_MACE=m
 CONFIG_BMAC=m
 CONFIG_ATL1=m
@@ -435,7 +420,6 @@
 CONFIG_SUNDANCE=m
 CONFIG_FEC_MPC52xx=m
 CONFIG_GIANFAR=m
-CONFIG_PCMCIA_FMVJ18X=m
 CONFIG_E100=m
 CONFIG_E1000=m
 CONFIG_E1000E=m
@@ -448,14 +432,10 @@
 CONFIG_FEALNX=m
 CONFIG_NATSEMI=m
 CONFIG_NS83820=m
-CONFIG_PCMCIA_AXNET=m
 CONFIG_NE2000=m
 CONFIG_NE2K_PCI=m
 CONFIG_PCMCIA_PCNET=m
-CONFIG_ULTRA=m
 CONFIG_FORCEDETH=m
-CONFIG_HAMACHI=m
-CONFIG_YELLOWFIN=m
 CONFIG_QLA3XXX=m
 CONFIG_NETXEN_NIC=m
 CONFIG_8139CP=m
@@ -468,7 +448,6 @@
 CONFIG_SIS900=m
 CONFIG_SIS190=m
 CONFIG_SFC=m
-CONFIG_PCMCIA_SMC91C92=m
 CONFIG_EPIC100=m
 CONFIG_HAPPYMEAL=m
 CONFIG_SUNGEM=m
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 4a27131..e18a4fa 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -438,7 +438,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
 	return true;
 }
 
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return pte_present(pte) && !is_kernel_addr(addr);
 }
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index a800350..e67e64a 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -549,7 +549,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
 	return arch_pte_access_permitted(pte_val(pte), write, 0);
 }
 
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return pte_present(pte) && pte_user(pte);
 }
@@ -925,9 +925,9 @@ static inline bool pud_access_permitted(pud_t pud, bool write)
 }
 
 #define pud_user_accessible_page pud_user_accessible_page
-static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
+static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
 {
-	return pud_leaf(pud) && pte_user_accessible_page(pud_pte(pud), addr);
+	return pud_leaf(pud) && pte_user_accessible_page(mm, addr, pud_pte(pud));
 }
 
 #define __p4d_raw(x)	((p4d_t) { __pgd_raw(x) })
@@ -1096,9 +1096,9 @@ static inline bool pmd_access_permitted(pmd_t pmd, bool write)
 }
 
 #define pmd_user_accessible_page pmd_user_accessible_page
-static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
+static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
 {
-	return pmd_leaf(pmd) && pte_user_accessible_page(pmd_pte(pmd), addr);
+	return pmd_leaf(pmd) && pte_user_accessible_page(mm, addr, pmd_pte(pmd));
 }
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
diff --git a/arch/powerpc/include/asm/nohash/pgtable.h b/arch/powerpc/include/asm/nohash/pgtable.h
index 3a6f20a..59375f3 100644
--- a/arch/powerpc/include/asm/nohash/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/pgtable.h
@@ -249,7 +249,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)
 	return true;
 }
 
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return pte_present(pte) && !is_kernel_addr(addr);
 }
diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h
index 138289a..d20ff2a 100644
--- a/arch/powerpc/include/asm/pgtable.h
+++ b/arch/powerpc/include/asm/pgtable.h
@@ -213,11 +213,11 @@ static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)
 #endif /* CONFIG_PPC64 */
 
 #ifndef pmd_user_accessible_page
-#define pmd_user_accessible_page(pmd, addr)	false
+#define pmd_user_accessible_page(mm, addr, pmd)	false
 #endif
 
 #ifndef pud_user_accessible_page
-#define pud_user_accessible_page(pud, addr)	false
+#define pud_user_accessible_page(mm, addr, pud)	false
 #endif
 
 #endif /* __ASSEMBLER__ */
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 4ebc333..501d43b 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -775,24 +775,12 @@ void __init fadump_update_elfcore_header(char *bufp)
 
 static void *__init fadump_alloc_buffer(unsigned long size)
 {
-	unsigned long count, i;
-	struct page *page;
-	void *vaddr;
-
-	vaddr = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-	if (!vaddr)
-		return NULL;
-
-	count = PAGE_ALIGN(size) / PAGE_SIZE;
-	page = virt_to_page(vaddr);
-	for (i = 0; i < count; i++)
-		mark_page_reserved(page + i);
-	return vaddr;
+	return  alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
 }
 
 static void fadump_free_buffer(unsigned long vaddr, unsigned long size)
 {
-	free_reserved_area((void *)vaddr, (void *)(vaddr + size), -1, NULL);
+	free_pages_exact((void *)vaddr, size);
 }
 
 s32 __init fadump_setup_cpu_notes_buf(u32 num_cpus)
diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c
index e76e462..32662d3 100644
--- a/arch/powerpc/platforms/powernv/opal-core.c
+++ b/arch/powerpc/platforms/powernv/opal-core.c
@@ -303,7 +303,6 @@ static int __init create_opalcore(void)
 	struct device_node *dn;
 	struct opalcore *new;
 	loff_t opalcore_off;
-	struct page *page;
 	Elf64_Phdr *phdr;
 	Elf64_Ehdr *elf;
 	int i, ret;
@@ -328,11 +327,6 @@ static int __init create_opalcore(void)
 		oc_conf->opalcorebuf_sz = 0;
 		return -ENOMEM;
 	}
-	count = oc_conf->opalcorebuf_sz / PAGE_SIZE;
-	page = virt_to_page(oc_conf->opalcorebuf);
-	for (i = 0; i < count; i++)
-		mark_page_reserved(page + i);
-
 	pr_debug("opalcorebuf = 0x%llx\n", (u64)oc_conf->opalcorebuf);
 
 	/* Read OPAL related device-tree entries */
@@ -437,10 +431,7 @@ static void opalcore_cleanup(void)
 
 	/* free the buffer used for setting up OPAL core */
 	if (oc_conf->opalcorebuf) {
-		void *end = (void *)((u64)oc_conf->opalcorebuf +
-				     oc_conf->opalcorebuf_sz);
-
-		free_reserved_area(oc_conf->opalcorebuf, end, -1, NULL);
+		free_pages_exact(oc_conf->opalcorebuf, oc_conf->opalcorebuf_sz);
 		oc_conf->opalcorebuf = NULL;
 		oc_conf->opalcorebuf_sz = 0;
 	}
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 53da345..d235396 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -47,8 +47,8 @@
 	select ARCH_HAS_PTE_SPECIAL
 	select ARCH_HAS_SET_DIRECT_MAP if MMU
 	select ARCH_HAS_SET_MEMORY if MMU
-	select ARCH_HAS_STRICT_KERNEL_RWX if MMU && !XIP_KERNEL
-	select ARCH_HAS_STRICT_MODULE_RWX if MMU && !XIP_KERNEL
+	select ARCH_HAS_STRICT_KERNEL_RWX if MMU
+	select ARCH_HAS_STRICT_MODULE_RWX if MMU
 	select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
 	select ARCH_HAS_SYSCALL_WRAPPER
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
@@ -84,7 +84,7 @@
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT
 	select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
-	select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL
+	select ARCH_WANT_LD_ORPHAN_WARN
 	select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP
 	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
 	select ARCH_WANTS_NO_INSTR
@@ -112,6 +112,7 @@
 	select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO && 64BIT
 	select GENERIC_IDLE_POLL_SETUP
 	select GENERIC_IOREMAP if MMU
+	select HAVE_IOREMAP_PROT if MMU
 	select GENERIC_IRQ_IPI if SMP
 	select GENERIC_IRQ_IPI_MUX if SMP
 	select GENERIC_IRQ_MULTI_HANDLER
@@ -129,13 +130,13 @@
 	select HAVE_ARCH_AUDITSYSCALL
 	select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
 	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_JUMP_LABEL
+	select HAVE_ARCH_JUMP_LABEL_RELATIVE
 	select HAVE_ARCH_KASAN if MMU && 64BIT
 	select HAVE_ARCH_KASAN_VMALLOC if MMU && 64BIT
 	select HAVE_ARCH_KFENCE if MMU && 64BIT
 	select HAVE_ARCH_KSTACK_ERASE
-	select HAVE_ARCH_KGDB if !XIP_KERNEL
+	select HAVE_ARCH_KGDB
 	select HAVE_ARCH_KGDB_QXFER_PKT
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
 	select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
@@ -153,7 +154,7 @@
 	select HAVE_CONTEXT_TRACKING_USER
 	select HAVE_DEBUG_KMEMLEAK
 	select HAVE_DMA_CONTIGUOUS if MMU
-	select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
+	select HAVE_DYNAMIC_FTRACE if MMU && (CLANG_SUPPORTS_DYNAMIC_FTRACE || GCC_SUPPORTS_DYNAMIC_FTRACE)
 	select FUNCTION_ALIGNMENT_4B if HAVE_DYNAMIC_FTRACE && RISCV_ISA_C
 	select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS if HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS
 	select HAVE_DYNAMIC_FTRACE_WITH_CALL_OPS if (DYNAMIC_FTRACE_WITH_ARGS && !CFI)
@@ -161,7 +162,7 @@
 	select HAVE_FTRACE_GRAPH_FUNC
 	select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS
 	select HAVE_FUNCTION_GRAPH_FREGS
-	select HAVE_FUNCTION_TRACER if !XIP_KERNEL && HAVE_DYNAMIC_FTRACE
+	select HAVE_FUNCTION_TRACER if HAVE_DYNAMIC_FTRACE
 	select HAVE_EBPF_JIT if MMU
 	select HAVE_GENERIC_TIF_BITS
 	select HAVE_GUP_FAST if MMU
@@ -170,16 +171,16 @@
 	select HAVE_GCC_PLUGINS
 	select HAVE_GENERIC_VDSO if MMU
 	select HAVE_IRQ_TIME_ACCOUNTING
-	select HAVE_KERNEL_BZIP2 if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_GZIP if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_LZ4 if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_LZMA if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_LZO if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_UNCOMPRESSED if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_ZSTD if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KERNEL_XZ if !XIP_KERNEL && !EFI_ZBOOT
-	select HAVE_KPROBES if !XIP_KERNEL
-	select HAVE_KRETPROBES if !XIP_KERNEL
+	select HAVE_KERNEL_BZIP2 if !EFI_ZBOOT
+	select HAVE_KERNEL_GZIP if !EFI_ZBOOT
+	select HAVE_KERNEL_LZ4 if !EFI_ZBOOT
+	select HAVE_KERNEL_LZMA if !EFI_ZBOOT
+	select HAVE_KERNEL_LZO if !EFI_ZBOOT
+	select HAVE_KERNEL_UNCOMPRESSED if !EFI_ZBOOT
+	select HAVE_KERNEL_ZSTD if !EFI_ZBOOT
+	select HAVE_KERNEL_XZ if !EFI_ZBOOT
+	select HAVE_KPROBES
+	select HAVE_KRETPROBES
 	# https://github.com/ClangBuiltLinux/linux/issues/1881
 	select HAVE_LD_DEAD_CODE_DATA_ELIMINATION if !LD_IS_LLD
 	select HAVE_MOVE_PMD
@@ -190,9 +191,9 @@
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
-	select HAVE_PREEMPT_DYNAMIC_KEY if !XIP_KERNEL
+	select HAVE_PREEMPT_DYNAMIC_KEY
 	select HAVE_REGS_AND_STACK_ACCESS_API
-	select HAVE_RETHOOK if !XIP_KERNEL
+	select HAVE_RETHOOK
 	select HAVE_RSEQ
 	select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG
 	select HAVE_SAMPLE_FTRACE_DIRECT
@@ -213,7 +214,7 @@
 	select PCI_ECAM if (ACPI && PCI)
 	select PCI_MSI if PCI
 	select RELOCATABLE if !MMU && !PHYS_RAM_BASE_FIXED
-	select RISCV_ALTERNATIVE if !XIP_KERNEL
+	select RISCV_ALTERNATIVE
 	select RISCV_APLIC
 	select RISCV_IMSIC
 	select RISCV_INTC
@@ -537,7 +538,6 @@
 
 config RISCV_ALTERNATIVE
 	bool
-	depends on !XIP_KERNEL
 	help
 	  This Kconfig allows the kernel to automatically patch the
 	  erratum or cpufeature required by the execution platform at run
@@ -1126,7 +1126,6 @@
 
 config RELOCATABLE
 	bool "Build a relocatable kernel"
-	depends on !XIP_KERNEL
 	select MODULE_SECTIONS if MODULES
 	select ARCH_VMLINUX_NEEDS_RELOCS
 	help
@@ -1143,7 +1142,7 @@
 config RANDOMIZE_BASE
         bool "Randomize the address of the kernel image"
         select RELOCATABLE
-        depends on MMU && 64BIT && !XIP_KERNEL
+        depends on MMU && 64BIT
         help
           Randomizes the virtual address at which the kernel image is
           loaded, as a security feature that deters exploit attempts
@@ -1233,7 +1232,7 @@
 
 config EFI
 	bool "UEFI runtime support"
-	depends on OF && !XIP_KERNEL
+	depends on OF
 	depends on MMU
 	default y
 	select ARCH_SUPPORTS_ACPI if 64BIT
@@ -1284,44 +1283,6 @@
 	  explicitly specified to run early relocations of read-write data
 	  from flash to RAM.
 
-config XIP_KERNEL
-	bool "Kernel Execute-In-Place from ROM"
-	depends on MMU && SPARSEMEM && NONPORTABLE
-	# This prevents XIP from being enabled by all{yes,mod}config, which
-	# fail to build since XIP doesn't support large kernels.
-	depends on !COMPILE_TEST
-	select PHYS_RAM_BASE_FIXED
-	help
-	  Execute-In-Place allows the kernel to run from non-volatile storage
-	  directly addressable by the CPU, such as NOR flash. This saves RAM
-	  space since the text section of the kernel is not loaded from flash
-	  to RAM.  Read-write sections, such as the data section and stack,
-	  are still copied to RAM.  The XIP kernel is not compressed since
-	  it has to run directly from flash, so it will take more space to
-	  store it.  The flash address used to link the kernel object files,
-	  and for storing it, is configuration dependent. Therefore, if you
-	  say Y here, you must know the proper physical address where to
-	  store the kernel image depending on your own flash memory usage.
-
-	  Also note that the make target becomes "make xipImage" rather than
-	  "make zImage" or "make Image".  The final kernel binary to put in
-	  ROM memory will be arch/riscv/boot/xipImage.
-
-	  SPARSEMEM is required because the kernel text and rodata that are
-	  flash resident are not backed by memmap, then any attempt to get
-	  a struct page on those regions will trigger a fault.
-
-	  If unsure, say N.
-
-config XIP_PHYS_ADDR
-	hex "XIP Kernel Physical Location"
-	depends on XIP_KERNEL
-	default "0x21000000"
-	help
-	  This is the physical address in your flash memory the kernel will
-	  be linked for and stored to.  This address is dependent on your
-	  own flash usage.
-
 config RISCV_ISA_FALLBACK
 	bool "Permit falling back to parsing riscv,isa for extension support by default"
 	default y
diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs
index d621b85..c174ac0 100644
--- a/arch/riscv/Kconfig.socs
+++ b/arch/riscv/Kconfig.socs
@@ -2,7 +2,7 @@
 
 config ARCH_ANDES
 	bool "Andes SoCs"
-	depends on MMU && !XIP_KERNEL
+	depends on MMU
 	select ERRATA_ANDES
 	help
 	  This enables support for Andes SoC platform hardware.
@@ -33,7 +33,7 @@
 
 config ARCH_SIFIVE
 	bool "SiFive SoCs"
-	select ERRATA_SIFIVE if !XIP_KERNEL
+	select ERRATA_SIFIVE
 	help
 	  This enables support for SiFive SoC platform hardware.
 
@@ -61,7 +61,7 @@
 
 config ARCH_SUNXI
 	bool "Allwinner sun20i SoCs"
-	depends on MMU && !XIP_KERNEL
+	depends on MMU
 	select ERRATA_THEAD
 	select SUN4I_TIMER
 	help
@@ -78,7 +78,7 @@
 
 config ARCH_THEAD
 	bool "T-HEAD RISC-V SoCs"
-	depends on MMU && !XIP_KERNEL
+	depends on MMU
 	select ERRATA_THEAD
 	select PM_GENERIC_DOMAINS if PM
 	help
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 371da75..ce0cc73 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -28,7 +28,6 @@
 export BITS
 ifeq ($(CONFIG_ARCH_RV64I),y)
 	BITS := 64
-	UTS_MACHINE := riscv64
 
 	KBUILD_CFLAGS += -mabi=lp64
 	KBUILD_AFLAGS += -mabi=lp64
@@ -39,13 +38,14 @@
 			    -Cno-redzone
 else
 	BITS := 32
-	UTS_MACHINE := riscv32
 
 	KBUILD_CFLAGS += -mabi=ilp32
 	KBUILD_AFLAGS += -mabi=ilp32
 	KBUILD_LDFLAGS += -melf32lriscv
 endif
 
+UTS_MACHINE := riscv$(BITS)
+
 # LLVM has an issue with target-features and LTO: https://github.com/llvm/llvm-project/issues/59350
 # Ensure it is aware of linker relaxation with LTO, otherwise relocations may
 # be incorrect: https://github.com/llvm/llvm-project/issues/65090
@@ -150,7 +150,6 @@
 boot-image-$(CONFIG_SOC_CANAAN_K210)	:= loader.bin
 endif
 boot-image-$(CONFIG_EFI_ZBOOT)		:= vmlinuz.efi
-boot-image-$(CONFIG_XIP_KERNEL)		:= xipImage
 KBUILD_IMAGE				:= $(boot)/$(boot-image-y)
 
 libs-y += arch/riscv/lib/
@@ -218,8 +217,6 @@
   echo  '  Image.xz	- Compressed kernel image (arch/riscv/boot/Image.xz)'
   echo  '  vmlinuz.efi	- Compressed EFI kernel image (arch/riscv/boot/vmlinuz.efi)'
   echo  '		  Default when CONFIG_EFI_ZBOOT=y'
-  echo  '  xipImage	- Execute-in-place kernel image (arch/riscv/boot/xipImage)'
-  echo  '		  Default when CONFIG_XIP_KERNEL=y'
   echo  '  install	- Install kernel using (your) ~/bin/$(INSTALLKERNEL) or'
   echo  '		  (distribution) /sbin/$(INSTALLKERNEL) or install to '
   echo  '		  $$(INSTALL_PATH)'
diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
index 5301adf..fcfbe3f 100644
--- a/arch/riscv/boot/Makefile
+++ b/arch/riscv/boot/Makefile
@@ -20,17 +20,6 @@
 
 targets := Image Image.* loader loader.o loader.lds loader.bin xipImage
 
-ifeq ($(CONFIG_XIP_KERNEL),y)
-
-quiet_cmd_mkxip = $(quiet_cmd_objcopy)
-cmd_mkxip = $(cmd_objcopy)
-
-$(obj)/xipImage: vmlinux FORCE
-	$(call if_changed,mkxip)
-	@$(kecho) '  Physical Address of xipImage: $(CONFIG_XIP_PHYS_ADDR)'
-
-endif
-
 $(obj)/Image: vmlinux FORCE
 	$(call if_changed,objcopy)
 
diff --git a/arch/riscv/errata/thead/errata.c b/arch/riscv/errata/thead/errata.c
index 0b94218..6f1c683 100644
--- a/arch/riscv/errata/thead/errata.c
+++ b/arch/riscv/errata/thead/errata.c
@@ -153,7 +153,7 @@ static bool errata_probe_ghostwrite(unsigned int stage,
 	 * target-c9xx cores report arch_id and impid as 0
 	 *
 	 * While ghostwrite may not affect all c9xx cores that implement
-	 * xtheadvector, there is no futher granularity than c9xx. Assume
+	 * xtheadvector, there is no further granularity than c9xx. Assume
 	 * vulnerable for this entire class of processors when xtheadvector is
 	 * enabled.
 	 */
diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
index 41ec5cd..5b90ba5 100644
--- a/arch/riscv/include/asm/asm-prototypes.h
+++ b/arch/riscv/include/asm/asm-prototypes.h
@@ -40,6 +40,7 @@ asmlinkage void riscv_v_context_nesting_end(struct pt_regs *regs);
 #define DECLARE_DO_ERROR_INFO(name)	asmlinkage void name(struct pt_regs *regs)
 
 DECLARE_DO_ERROR_INFO(do_trap_unknown);
+DECLARE_DO_ERROR_INFO(do_trap_hardware_error);
 DECLARE_DO_ERROR_INFO(do_trap_insn_misaligned);
 DECLARE_DO_ERROR_INFO(do_trap_insn_fault);
 DECLARE_DO_ERROR_INFO(do_trap_insn_illegal);
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index 3f33dc5..616b8b3 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -46,7 +46,7 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
 #endif
 
 /*
- * First, the atomic ops that have no ordering constraints and therefor don't
+ * First, the atomic ops that have no ordering constraints and therefore don't
  * have the AQ or RL bits set.  These don't return anything, so there's only
  * one version to worry about.
  */
@@ -81,7 +81,7 @@ ATOMIC_OPS(xor, xor,  i)
 
 /*
  * Atomic ops that have ordered, relaxed, acquire, and release variants.
- * There's two flavors of these: the arithmatic ops have both fetch and return
+ * There's two flavors of these: the arithmetic ops have both fetch and return
  * versions, while the logical ops only have fetch versions.
  */
 #define ATOMIC_FETCH_OP(op, asm_op, I, asm_type, c_type, prefix)	\
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index c7aea78..aa4961b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -59,8 +59,8 @@ extern bool compat_elf_check_arch(Elf32_Ehdr *hdr);
 #endif
 
 /*
- * Provides information on the availiable set of ISA extensions to userspace,
- * via a bitmap that coorespends to each single-letter ISA extension.  This is
+ * Provides information on the available set of ISA extensions to userspace,
+ * via a bitmap that corresponds to each single-letter ISA extension.  This is
  * essentially defunct, but will remain for compatibility with userspace.
  */
 #define ELF_HWCAP	riscv_get_elf_hwcap()
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index c780170..709a36f 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -29,11 +29,7 @@
 #define PAGE_OFFSET_L5		_AC(0xff60000000000000, UL)
 #define PAGE_OFFSET_L4		_AC(0xffffaf8000000000, UL)
 #define PAGE_OFFSET_L3		_AC(0xffffffd600000000, UL)
-#ifdef CONFIG_XIP_KERNEL
-#define PAGE_OFFSET		PAGE_OFFSET_L3
-#else
 #define PAGE_OFFSET		kernel_map.page_offset
-#endif /* CONFIG_XIP_KERNEL */
 #else
 #define PAGE_OFFSET		_AC(0xc0000000, UL)
 #endif /* CONFIG_64BIT */
@@ -104,15 +100,8 @@ struct kernel_mapping {
 	/* Offset between linear mapping virtual address and kernel load address */
 	unsigned long va_pa_offset;
 	/* Offset between kernel mapping virtual address and kernel load address */
-#ifdef CONFIG_XIP_KERNEL
-	unsigned long va_kernel_xip_text_pa_offset;
-	unsigned long va_kernel_xip_data_pa_offset;
-	uintptr_t xiprom;
-	uintptr_t xiprom_sz;
-#else
 	unsigned long page_offset;
 	unsigned long va_kernel_pa_offset;
-#endif
 };
 
 extern struct kernel_mapping kernel_map;
@@ -131,16 +120,7 @@ extern unsigned long vmemmap_start_pfn;
 void *linear_mapping_pa_to_va(unsigned long x);
 #endif
 
-#ifdef CONFIG_XIP_KERNEL
-#define kernel_mapping_pa_to_va(y)	({					\
-	unsigned long _y = (unsigned long)(y);					\
-	(_y < phys_ram_base) ?							\
-		(void *)(_y + kernel_map.va_kernel_xip_text_pa_offset) :	\
-		(void *)(_y + kernel_map.va_kernel_xip_data_pa_offset);		\
-	})
-#else
 #define kernel_mapping_pa_to_va(y) ((void *)((unsigned long)(y) + kernel_map.va_kernel_pa_offset))
-#endif
 
 #define __pa_to_va_nodebug(x)		linear_mapping_pa_to_va(x)
 
@@ -150,16 +130,7 @@ void *linear_mapping_pa_to_va(unsigned long x);
 phys_addr_t linear_mapping_va_to_pa(unsigned long x);
 #endif
 
-#ifdef CONFIG_XIP_KERNEL
-#define kernel_mapping_va_to_pa(y) ({						\
-	unsigned long _y = (unsigned long)(y);					\
-	(_y < kernel_map.virt_addr + kernel_map.xiprom_sz) ?			\
-		(_y - kernel_map.va_kernel_xip_text_pa_offset) :		\
-		(_y - kernel_map.va_kernel_xip_data_pa_offset);			\
-	})
-#else
 #define kernel_mapping_va_to_pa(y) ((unsigned long)(y) - kernel_map.va_kernel_pa_offset)
-#endif
 
 #define __va_to_pa_nodebug(x)	({						\
 	unsigned long _x = x;							\
@@ -190,7 +161,10 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
 
 #define sym_to_pfn(x)           __phys_to_pfn(__pa_symbol(x))
 
-unsigned long kaslr_offset(void);
+static inline unsigned long kaslr_offset(void)
+{
+	return kernel_map.virt_offset;
+}
 
 static __always_inline void *pfn_to_kaddr(unsigned long pfn)
 {
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index a6e0eab..a1a7c65 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -134,21 +134,6 @@
 
 #include <linux/page_table_check.h>
 
-#ifdef CONFIG_XIP_KERNEL
-#define XIP_FIXUP(addr) ({							\
-	extern char _sdata[], _start[], _end[];					\
-	uintptr_t __rom_start_data = CONFIG_XIP_PHYS_ADDR			\
-				+ (uintptr_t)&_sdata - (uintptr_t)&_start;	\
-	uintptr_t __rom_end_data = CONFIG_XIP_PHYS_ADDR				\
-				+ (uintptr_t)&_end - (uintptr_t)&_start;	\
-	uintptr_t __a = (uintptr_t)(addr);					\
-	(__a >= __rom_start_data && __a < __rom_end_data) ?			\
-		__a - __rom_start_data + CONFIG_PHYS_RAM_BASE :	__a;		\
-	})
-#else
-#define XIP_FIXUP(addr)		(addr)
-#endif /* CONFIG_XIP_KERNEL */
-
 struct pt_alloc_ops {
 	pte_t *(*get_pte_virt)(phys_addr_t pa);
 	phys_addr_t (*alloc_pte)(uintptr_t va);
@@ -984,17 +969,17 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
 }
 
 #ifdef CONFIG_PAGE_TABLE_CHECK
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return pte_present(pte) && pte_user(pte);
 }
 
-static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
+static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
 {
 	return pmd_leaf(pmd) && pmd_user(pmd);
 }
 
-static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
+static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
 {
 	return pud_leaf(pud) && pud_user(pud);
 }
@@ -1272,13 +1257,8 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
 extern char _start[];
 extern void *_dtb_early_va;
 extern uintptr_t _dtb_early_pa;
-#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_MMU)
-#define dtb_early_va	(*(void **)XIP_FIXUP(&_dtb_early_va))
-#define dtb_early_pa	(*(uintptr_t *)XIP_FIXUP(&_dtb_early_pa))
-#else
 #define dtb_early_va	_dtb_early_va
 #define dtb_early_pa	_dtb_early_pa
-#endif /* CONFIG_XIP_KERNEL */
 extern u64 satp_mode;
 
 void paging_init(void);
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 4c3dd94..812517b 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -86,7 +86,7 @@ struct pt_regs;
  *    preempt_v. All preempt_v context should be dropped in such case because
  *    V-regs are caller-saved. Only sstatus.VS=ON is persisted across a
  *    schedule() call.
- *  - bit 30: The in-kernel preempt_v context is saved, and requries to be
+ *  - bit 30: The in-kernel preempt_v context is saved, and is required to be
  *    restored when returning to the context that owns the preempt_v.
  *  - bit 31: The in-kernel preempt_v context is dirty, as signaled by the
  *    trap entry code. Any context switches out-of current task need to save
diff --git a/arch/riscv/include/asm/scs.h b/arch/riscv/include/asm/scs.h
index ab7714a..023a412f 100644
--- a/arch/riscv/include/asm/scs.h
+++ b/arch/riscv/include/asm/scs.h
@@ -10,7 +10,6 @@
 /* Load init_shadow_call_stack to gp. */
 .macro scs_load_init_stack
 	la	gp, init_shadow_call_stack
-	XIP_FIXUP_OFFSET gp
 .endm
 
 /* Load the per-CPU IRQ shadow call stack to gp. */
diff --git a/arch/riscv/include/asm/set_memory.h b/arch/riscv/include/asm/set_memory.h
index 87389e9..ef59e17 100644
--- a/arch/riscv/include/asm/set_memory.h
+++ b/arch/riscv/include/asm/set_memory.h
@@ -47,7 +47,7 @@ bool kernel_page_present(struct page *page);
 
 #endif /* __ASSEMBLER__ */
 
-#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_XIP_KERNEL)
+#if defined(CONFIG_STRICT_KERNEL_RWX)
 #ifdef CONFIG_64BIT
 #define SECTION_ALIGN (1 << 21)
 #else
diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h
index 7ac80e9..0ecc676 100644
--- a/arch/riscv/include/asm/smp.h
+++ b/arch/riscv/include/asm/smp.h
@@ -105,7 +105,7 @@ static inline void riscv_ipi_set_virq_range(int virq, int nr)
 
 #endif /* CONFIG_SMP */
 
-#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)
+#if defined(CONFIG_HOTPLUG_CPU)
 bool cpu_has_hotplug(unsigned int cpu);
 #else
 static inline bool cpu_has_hotplug(unsigned int cpu)
diff --git a/arch/riscv/include/asm/string.h b/arch/riscv/include/asm/string.h
index 5ba77f6..764ffe8 100644
--- a/arch/riscv/include/asm/string.h
+++ b/arch/riscv/include/asm/string.h
@@ -28,6 +28,15 @@ extern asmlinkage __kernel_size_t strlen(const char *);
 
 #define __HAVE_ARCH_STRNCMP
 extern asmlinkage int strncmp(const char *cs, const char *ct, size_t count);
+
+#define __HAVE_ARCH_STRNLEN
+extern asmlinkage __kernel_size_t strnlen(const char *, size_t);
+
+#define __HAVE_ARCH_STRCHR
+extern asmlinkage char *strchr(const char *, int);
+
+#define __HAVE_ARCH_STRRCHR
+extern asmlinkage char *strrchr(const char *, int);
 #endif
 
 /* For those files which don't want to check by kasan. */
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 36918c9..55019fd 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -120,7 +120,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
 #include <asm-generic/thread_info_tif.h>
 
 #define TIF_32BIT			16	/* compat-mode 32bit process */
-#define TIF_RISCV_V_DEFER_RESTORE	17	/* restore Vector before returing to user */
+#define TIF_RISCV_V_DEFER_RESTORE	17	/* restore Vector before returning to user */
 
 #define _TIF_RISCV_V_DEFER_RESTORE	BIT(TIF_RISCV_V_DEFER_RESTORE)
 
diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h
deleted file mode 100644
index f3d5629..0000000
--- a/arch/riscv/include/asm/xip_fixup.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * XIP fixup macros, only useful in assembly.
- */
-#ifndef _ASM_RISCV_XIP_FIXUP_H
-#define _ASM_RISCV_XIP_FIXUP_H
-
-#include <linux/pgtable.h>
-
-#ifdef CONFIG_XIP_KERNEL
-.macro XIP_FIXUP_OFFSET reg
-	/* Fix-up address in Flash into address in RAM early during boot before
-	 * MMU is up. Because generated code "thinks" data is in Flash, but it
-	 * is actually in RAM (actually data is also in Flash, but Flash is
-	 * read-only, thus we need to use the data residing in RAM).
-	 *
-	 * The start of data in Flash is _sdata and the start of data in RAM is
-	 * CONFIG_PHYS_RAM_BASE. So this fix-up essentially does this:
-	 * reg += CONFIG_PHYS_RAM_BASE - _start
-	 */
-	li t0, CONFIG_PHYS_RAM_BASE
-        add \reg, \reg, t0
-	la t0, _sdata
-	sub \reg, \reg, t0
-.endm
-.macro XIP_FIXUP_FLASH_OFFSET reg
-	/* In linker script, at the transition from read-only section to
-	 * writable section, the VMA is increased while LMA remains the same.
-	 * (See in linker script how _sdata, __data_loc and LOAD_OFFSET is
-	 * changed)
-	 *
-	 * Consequently, early during boot before MMU is up, the generated code
-	 * reads the "writable" section at wrong addresses, because VMA is used
-	 * by compiler to generate code, but the data is located in Flash using
-	 * LMA.
-	 */
-	la t0, _sdata
-	sub \reg, \reg, t0
-	la t0, __data_loc
-	add \reg, \reg, t0
-.endm
-#else
-.macro XIP_FIXUP_OFFSET reg
-.endm
-.macro XIP_FIXUP_FLASH_OFFSET reg
-.endm
-#endif /* CONFIG_XIP_KERNEL */
-
-#endif
diff --git a/arch/riscv/include/uapi/asm/setup.h b/arch/riscv/include/uapi/asm/setup.h
index 66b13a5..eb4f020 100644
--- a/arch/riscv/include/uapi/asm/setup.h
+++ b/arch/riscv/include/uapi/asm/setup.h
@@ -3,6 +3,6 @@
 #ifndef _UAPI_ASM_RISCV_SETUP_H
 #define _UAPI_ASM_RISCV_SETUP_H
 
-#define COMMAND_LINE_SIZE	1024
+#define COMMAND_LINE_SIZE	2048
 
 #endif /* _UAPI_ASM_RISCV_SETUP_H */
diff --git a/arch/riscv/kernel/acpi.c b/arch/riscv/kernel/acpi.c
index 322ea92..068e0b4 100644
--- a/arch/riscv/kernel/acpi.c
+++ b/arch/riscv/kernel/acpi.c
@@ -69,7 +69,7 @@ static int __init acpi_fadt_sanity_check(void)
 
 	/*
 	 * FADT is required on riscv; retrieve it to check its presence
-	 * and carry out revision and ACPI HW reduced compliancy tests
+	 * and carry out revision and ACPI HW reduced compliance tests
 	 */
 	status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
 	if (ACPI_FAILURE(status)) {
@@ -85,12 +85,12 @@ static int __init acpi_fadt_sanity_check(void)
 	 * The revision in the table header is the FADT's Major revision. The
 	 * FADT also has a minor revision, which is stored in the FADT itself.
 	 *
-	 * TODO: Currently, we check for 6.5 as the minimum version to check
-	 * for HW_REDUCED flag. However, once RISC-V updates are released in
-	 * the ACPI spec, we need to update this check for exact minor revision
+	 * ACPI 6.6 is required for RISC-V as it introduces RISC-V specific
+	 * tables such as RHCT (RISC-V Hart Capabilities Table) and RIMT
+	 * (RISC-V I/O Mapping Table).
 	 */
-	if (table->revision < 6 || (table->revision == 6 && fadt->minor_revision < 5))
-		pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 6.5+\n",
+	if (table->revision < 6 || (table->revision == 6 && fadt->minor_revision < 6))
+		pr_err(FW_BUG "Unsupported FADT revision %d.%d, should be 6.6+\n",
 		       table->revision, fadt->minor_revision);
 
 	if (!(fadt->flags & ACPI_FADT_HW_REDUCED)) {
diff --git a/arch/riscv/kernel/cpu-hotplug.c b/arch/riscv/kernel/cpu-hotplug.c
index 3f50d3d..a0ee426 100644
--- a/arch/riscv/kernel/cpu-hotplug.c
+++ b/arch/riscv/kernel/cpu-hotplug.c
@@ -43,7 +43,6 @@ int __cpu_disable(void)
 	return 0;
 }
 
-#ifdef CONFIG_HOTPLUG_CPU
 /*
  * Called on the thread which is asking for a CPU to be shutdown, if the
  * CPU reported dead to the hotplug core.
@@ -75,4 +74,3 @@ void __noreturn arch_cpu_idle_dead(void)
 	/* It should never reach here */
 	BUG();
 }
-#endif
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 60eb221..d011fb5 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -498,6 +498,7 @@
 	RISCV_PTR do_trap_unknown /* cause=16 */
 	RISCV_PTR do_trap_unknown /* cause=17 */
 	RISCV_PTR do_trap_software_check /* cause=18 is sw check exception */
+	RISCV_PTR do_trap_hardware_error /* hardware error (19) */
 SYM_DATA_END_LABEL(excp_vect_table, SYM_L_LOCAL, excp_vect_table_end)
 
 #ifndef CONFIG_MMU
diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c
index 8d18d67..b430edf 100644
--- a/arch/riscv/kernel/ftrace.c
+++ b/arch/riscv/kernel/ftrace.c
@@ -148,7 +148,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long ad
 
 /*
  * This is called early on, and isn't wrapped by
- * ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold
+ * ftrace_arch_code_modify_{prepare,post_process}() and therefore doesn't hold
  * text_mutex, which triggers a lockdep failure.  SMP isn't running so we could
  * just directly poke the text, but it's simpler to just take the lock
  * ourselves.
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 9c99c5ad..f6a8ca4 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -14,7 +14,6 @@
 #include <asm/hwcap.h>
 #include <asm/image.h>
 #include <asm/scs.h>
-#include <asm/xip_fixup.h>
 #include <asm/usercfi.h>
 #include "efi-header.S"
 
@@ -75,13 +74,12 @@
 relocate_enable_mmu:
 	/* Relocate return address */
 	la a1, kernel_map
-	XIP_FIXUP_OFFSET a1
 	REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
 	la a2, _start
 	sub a1, a1, a2
 	add ra, ra, a1
 
-	/* Point stvec to virtual address of intruction after satp write */
+	/* Point stvec to virtual address of instruction after satp write */
 	la a2, 1f
 	add a2, a2, a1
 	csrw CSR_TVEC, a2
@@ -89,7 +87,6 @@
 	/* Compute satp for kernel page tables, but don't load it yet */
 	srl a2, a0, PAGE_SHIFT
 	la a1, satp_mode
-	XIP_FIXUP_OFFSET a1
 	REG_L a1, 0(a1)
 	or a2, a2, a1
 
@@ -100,7 +97,6 @@
 	 * to ensure the new translations are in use.
 	 */
 	la a0, trampoline_pg_dir
-	XIP_FIXUP_OFFSET a0
 	srl a0, a0, PAGE_SHIFT
 	or a0, a0, a1
 	sfence.vma
@@ -154,11 +150,9 @@
 
 	/* a0 contains the hartid & a1 contains boot data */
 	li a2, SBI_HART_BOOT_TASK_PTR_OFFSET
-	XIP_FIXUP_OFFSET a2
 	add a2, a2, a1
 	REG_L tp, (a2)
 	li a3, SBI_HART_BOOT_STACK_PTR_OFFSET
-	XIP_FIXUP_OFFSET a3
 	add a3, a3, a1
 	REG_L sp, (a3)
 
@@ -167,7 +161,6 @@
 #ifdef CONFIG_MMU
 	/* Enable virtual memory and relocate to virtual address */
 	la a0, swapper_pg_dir
-	XIP_FIXUP_OFFSET a0
 	call relocate_enable_mmu
 #endif
 	call .Lsetup_trap_vector
@@ -269,40 +262,13 @@
 .Lgood_cores:
 
 	/* The lottery system is only required for spinwait booting method */
-#ifndef CONFIG_XIP_KERNEL
 	/* Pick one hart to run the main boot sequence */
 	la a3, hart_lottery
 	li a2, 1
 	amoadd.w a3, a2, (a3)
 	bnez a3, .Lsecondary_start
-
-#else
-	/* hart_lottery in flash contains a magic number */
-	la a3, hart_lottery
-	mv a2, a3
-	XIP_FIXUP_OFFSET a2
-	XIP_FIXUP_FLASH_OFFSET a3
-	lw t1, (a3)
-	amoswap.w t0, t1, (a2)
-	/* first time here if hart_lottery in RAM is not set */
-	beq t0, t1, .Lsecondary_start
-
-#endif /* CONFIG_XIP */
 #endif /* CONFIG_RISCV_BOOT_SPINWAIT */
 
-#ifdef CONFIG_XIP_KERNEL
-	la sp, _end + THREAD_SIZE
-	XIP_FIXUP_OFFSET sp
-	mv s0, a0
-	mv s1, a1
-	call __copy_data
-
-	/* Restore a0 & a1 copy */
-	mv a0, s0
-	mv a1, s1
-#endif
-
-#ifndef CONFIG_XIP_KERNEL
 	/* Clear BSS for flat non-ELF images */
 	la a3, __bss_start
 	la a4, __bss_stop
@@ -312,20 +278,16 @@
 	add a3, a3, RISCV_SZPTR
 	blt a3, a4, .Lclear_bss
 .Lclear_bss_done:
-#endif
 	la a2, boot_cpu_hartid
-	XIP_FIXUP_OFFSET a2
 	REG_S a0, (a2)
 
 	/* Initialize page tables and relocate to virtual addresses */
 	la tp, init_task
 	la sp, init_thread_union + THREAD_SIZE
-	XIP_FIXUP_OFFSET sp
 	addi sp, sp, -PT_SIZE_ON_STACK
 	scs_load_init_stack
 #ifdef CONFIG_BUILTIN_DTB
 	la a0, __dtb_start
-	XIP_FIXUP_OFFSET a0
 #else
 	mv a0, a1
 #endif /* CONFIG_BUILTIN_DTB */
@@ -335,7 +297,6 @@
 	call setup_vm
 #ifdef CONFIG_MMU
 	la a0, early_pg_dir
-	XIP_FIXUP_OFFSET a0
 	call relocate_enable_mmu
 #endif /* CONFIG_MMU */
 
@@ -374,9 +335,7 @@
 
 	slli a3, a0, LGREG
 	la a1, __cpu_spinwait_stack_pointer
-	XIP_FIXUP_OFFSET a1
 	la a2, __cpu_spinwait_task_pointer
-	XIP_FIXUP_OFFSET a2
 	add a1, a3, a1
 	add a2, a3, a2
 
diff --git a/arch/riscv/kernel/head.h b/arch/riscv/kernel/head.h
index a556fda..05a04be 100644
--- a/arch/riscv/kernel/head.h
+++ b/arch/riscv/kernel/head.h
@@ -11,9 +11,6 @@
 extern atomic_t hart_lottery;
 
 asmlinkage void __init setup_vm(uintptr_t dtb_pa);
-#ifdef CONFIG_XIP_KERNEL
-asmlinkage void __init __copy_data(void);
-#endif
 
 #ifdef CONFIG_RISCV_BOOT_SPINWAIT
 extern void *__cpu_spinwait_stack_pointer[];
diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S
index 48f6c4f..082fe0b 100644
--- a/arch/riscv/kernel/mcount-dyn.S
+++ b/arch/riscv/kernel/mcount-dyn.S
@@ -66,7 +66,7 @@
 * 8(sp) stores the function return address (i.e. parent IP) that
 * can be accessed by &(fregs)->ra in tracing function.
 *
-* The other regs are saved at the respective localtion and accessed
+* The other regs are saved at the respective location and accessed
 * by the respective ftrace_regs member.
 *
 * Here is the layout of stack for your reference.
diff --git a/arch/riscv/kernel/module-sections.c b/arch/riscv/kernel/module-sections.c
index 1675cba..98eaac6 100644
--- a/arch/riscv/kernel/module-sections.c
+++ b/arch/riscv/kernel/module-sections.c
@@ -148,7 +148,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
 		return -ENOEXEC;
 	}
 
-	/* Calculate the maxinum number of entries */
+	/* Calculate the maximum number of entries */
 	for (i = 0; i < ehdr->e_shnum; i++) {
 		size_t num_relas = sechdrs[i].sh_size / sizeof(Elf_Rela);
 		Elf_Rela *relas = (void *)ehdr + sechdrs[i].sh_offset;
diff --git a/arch/riscv/kernel/probes/kprobes.c b/arch/riscv/kernel/probes/kprobes.c
index 8723390..9e2afab 100644
--- a/arch/riscv/kernel/probes/kprobes.c
+++ b/arch/riscv/kernel/probes/kprobes.c
@@ -149,7 +149,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p)
 
 /*
  * Interrupts need to be disabled before single-step mode is set, and not
- * reenabled until after single-step mode ends.
+ * re-enabled until after single-step mode ends.
  * Without disabling interrupt on local CPU, there is a chance of
  * interrupt occurrence in the period of exception return and  start of
  * out-of-line single-step, that result in wrongly single stepping
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c
index f0d0691..eb177d0 100644
--- a/arch/riscv/kernel/probes/uprobes.c
+++ b/arch/riscv/kernel/probes/uprobes.c
@@ -111,7 +111,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 
 	current->thread.bad_cause = utask->autask.saved_cause;
 	/*
-	 * Task has received a fatal signal, so reset back to probbed
+	 * Task has received a fatal signal, so reset back to probed
 	 * address.
 	 */
 	instruction_pointer_set(regs, utask->vaddr);
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c
index b5bc5fc..c89cc27 100644
--- a/arch/riscv/kernel/setup.c
+++ b/arch/riscv/kernel/setup.c
@@ -46,11 +46,7 @@
  * This is used before the kernel initializes the BSS so it can't be in the
  * BSS.
  */
-atomic_t hart_lottery __section(".sdata")
-#ifdef CONFIG_XIP_KERNEL
-= ATOMIC_INIT(0xC001BEEF)
-#endif
-;
+atomic_t hart_lottery __section(".sdata");
 unsigned long boot_cpu_hartid;
 EXPORT_SYMBOL_GPL(boot_cpu_hartid);
 
diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c
index d85916a..8b62858 100644
--- a/arch/riscv/kernel/smpboot.c
+++ b/arch/riscv/kernel/smpboot.c
@@ -251,18 +251,14 @@ asmlinkage __visible void smp_callin(void)
 	set_cpu_online(curr_cpuid, true);
 
 	/*
-	 * Remote cache and TLB flushes are ignored while the CPU is offline,
-	 * so flush them both right now just in case.
+	 * Remote instruction 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();
 #ifndef CONFIG_HOTPLUG_PARALLEL
 	complete(&cpu_running);
 #endif
-	/*
-	 * Disable preemption before enabling interrupts, so we don't try to
-	 * schedule a CPU that hasn't actually started yet.
-	 */
 	local_irq_enable();
 	cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
 }
diff --git a/arch/riscv/kernel/soc.c b/arch/riscv/kernel/soc.c
index a051617..7d69e3b 100644
--- a/arch/riscv/kernel/soc.c
+++ b/arch/riscv/kernel/soc.c
@@ -8,7 +8,7 @@
 #include <asm/soc.h>
 
 /*
- * This is called extremly early, before parse_dtb(), to allow initializing
+ * This is called extremely early, before parse_dtb(), to allow initializing
  * SoC hardware before memory or any device driver initialization.
  */
 void __init soc_early_init(void)
diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c
index aff9309..3efbf78 100644
--- a/arch/riscv/kernel/suspend.c
+++ b/arch/riscv/kernel/suspend.c
@@ -78,7 +78,7 @@ int cpu_suspend(unsigned long arg,
 	suspend_save_csrs(&context);
 
 	/*
-	 * Function graph tracer state gets incosistent when the kernel
+	 * Function graph tracer state gets inconsistent when the kernel
 	 * calls functions that never return (aka finishers) hence disable
 	 * graph tracing during their execution.
 	 */
diff --git a/arch/riscv/kernel/suspend_entry.S b/arch/riscv/kernel/suspend_entry.S
index 2d54f30..d71b55f 100644
--- a/arch/riscv/kernel/suspend_entry.S
+++ b/arch/riscv/kernel/suspend_entry.S
@@ -10,7 +10,6 @@
 #include <asm/asm-offsets.h>
 #include <asm/assembler.h>
 #include <asm/csr.h>
-#include <asm/xip_fixup.h>
 
 	.text
 	.altmacro
@@ -70,7 +69,6 @@
 
 	/* Enable MMU */
 	la	a0, swapper_pg_dir
-	XIP_FIXUP_OFFSET a0
 	call	relocate_enable_mmu
 
 	/* Restore A0 and A1 */
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 461279a..8c62c77 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -142,11 +142,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
 	}
 }
 
-#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE)
-#define __trap_section __noinstr_section(".xip.traps")
-#else
 #define __trap_section noinstr
-#endif
 #define DO_ERROR_INFO(name, signo, code, str)					\
 asmlinkage __visible __trap_section void name(struct pt_regs *regs)		\
 {										\
@@ -165,6 +161,8 @@ asmlinkage __visible __trap_section void name(struct pt_regs *regs)		\
 
 DO_ERROR_INFO(do_trap_unknown,
 	SIGILL, ILL_ILLTRP, "unknown exception");
+DO_ERROR_INFO(do_trap_hardware_error,
+	SIGBUS, BUS_MCEERR_AR, "hardware error");
 DO_ERROR_INFO(do_trap_insn_misaligned,
 	SIGBUS, BUS_ADRALN, "instruction address misaligned");
 DO_ERROR_INFO(do_trap_insn_fault,
diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c
index b36a6a5..485ab1d 100644
--- a/arch/riscv/kernel/unaligned_access_speed.c
+++ b/arch/riscv/kernel/unaligned_access_speed.c
@@ -16,7 +16,7 @@
 
 #include "copy-unaligned.h"
 
-#define MISALIGNED_ACCESS_JIFFIES_LG2 1
+#define MISALIGNED_ACCESS_NS 8000000
 #define MISALIGNED_BUFFER_SIZE 0x4000
 #define MISALIGNED_BUFFER_ORDER get_order(MISALIGNED_BUFFER_SIZE)
 #define MISALIGNED_COPY_SIZE ((MISALIGNED_BUFFER_SIZE / 2) - 0x80)
@@ -29,109 +29,125 @@ static long unaligned_vector_speed_param = RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNO
 
 static cpumask_t fast_misaligned_access;
 
-#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS
-static int check_unaligned_access(void *param)
+static u64 __maybe_unused
+measure_cycles(void (*func)(void *dst, const void *src, size_t len),
+	       void *dst, void *src, size_t len)
 {
-	int cpu = smp_processor_id();
-	u64 start_cycles, end_cycles;
-	u64 word_cycles;
-	u64 byte_cycles;
-	int ratio;
-	unsigned long start_jiffies, now;
-	struct page *page = param;
-	void *dst;
-	void *src;
-	long speed = RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW;
+	u64 start_cycles, end_cycles, cycles = -1ULL;
+	u64 start_ns;
 
-	if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN)
-		return 0;
-
-	/* Make an unaligned destination buffer. */
-	dst = (void *)((unsigned long)page_address(page) | 0x1);
-	/* Unalign src as well, but differently (off by 1 + 2 = 3). */
-	src = dst + (MISALIGNED_BUFFER_SIZE / 2);
-	src += 2;
-	word_cycles = -1ULL;
 	/* Do a warmup. */
-	__riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+	func(dst, src, len);
+
 	preempt_disable();
-	start_jiffies = jiffies;
-	while ((now = jiffies) == start_jiffies)
-		cpu_relax();
 
 	/*
 	 * For a fixed amount of time, repeatedly try the function, and take
 	 * the best time in cycles as the measurement.
 	 */
-	while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
+	start_ns = ktime_get_mono_fast_ns();
+	while (ktime_get_mono_fast_ns() < start_ns + MISALIGNED_ACCESS_NS) {
 		start_cycles = get_cycles64();
 		/* Ensure the CSR read can't reorder WRT to the copy. */
 		mb();
-		__riscv_copy_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
+		func(dst, src, len);
 		/* Ensure the copy ends before the end time is snapped. */
 		mb();
 		end_cycles = get_cycles64();
-		if ((end_cycles - start_cycles) < word_cycles)
-			word_cycles = end_cycles - start_cycles;
-	}
-
-	byte_cycles = -1ULL;
-	__riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
-	start_jiffies = jiffies;
-	while ((now = jiffies) == start_jiffies)
-		cpu_relax();
-
-	while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
-		start_cycles = get_cycles64();
-		mb();
-		__riscv_copy_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
-		mb();
-		end_cycles = get_cycles64();
-		if ((end_cycles - start_cycles) < byte_cycles)
-			byte_cycles = end_cycles - start_cycles;
+		if ((end_cycles - start_cycles) < cycles)
+			cycles = end_cycles - start_cycles;
 	}
 
 	preempt_enable();
 
+	return cycles;
+}
+
+/*
+ * Return:
+ *     1 if unaligned accesses are fast
+ *     0 if unaligned accesses are slow
+ *    -1 if check cannot be done
+ */
+static int __maybe_unused
+compare_unaligned_access(void (*word_copy)(void *dst, const void *src, size_t len),
+			 void (*byte_copy)(void *dst, const void *src, size_t len),
+			 void *buf, const char *type)
+{
+	int cpu = smp_processor_id();
+	u64 word_cycles;
+	u64 byte_cycles;
+	void *dst, *src;
+	bool fast;
+	int ratio;
+
+	/* Make an unaligned destination buffer. */
+	dst = (void *)((unsigned long)buf | 0x1);
+	/* Unalign src as well, but differently (off by 1 + 2 = 3). */
+	src = dst + (MISALIGNED_BUFFER_SIZE / 2);
+	src += 2;
+
+	word_cycles = measure_cycles(word_copy, dst, src, MISALIGNED_COPY_SIZE);
+	byte_cycles = measure_cycles(byte_copy, dst, src, MISALIGNED_COPY_SIZE);
+
 	/* Don't divide by zero. */
 	if (!word_cycles || !byte_cycles) {
-		pr_warn("cpu%d: rdtime lacks granularity needed to measure unaligned access speed\n",
-			cpu);
+		pr_warn("cpu%d: rdtime lacks granularity needed to measure %s unaligned access speed\n",
+			cpu, type);
 
-		return 0;
+		return -1;
 	}
 
-	if (word_cycles < byte_cycles)
-		speed = RISCV_HWPROBE_MISALIGNED_SCALAR_FAST;
+	fast = word_cycles < byte_cycles;
 
 	ratio = div_u64((byte_cycles * 100), word_cycles);
-	pr_info("cpu%d: Ratio of byte access time to unaligned word access is %d.%02d, unaligned accesses are %s\n",
+	pr_info("cpu%d: %s unaligned word access speed is %d.%02dx byte access speed (%s)\n",
 		cpu,
+		type,
 		ratio / 100,
 		ratio % 100,
-		(speed == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST) ? "fast" : "slow");
+		fast ? "fast" : "slow");
 
-	per_cpu(misaligned_access_speed, cpu) = speed;
+	return fast;
+}
+
+#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS
+static int check_unaligned_access(struct page *page)
+{
+	void *buf = page_address(page);
+	int cpu = smp_processor_id();
+	int ret;
+
+	if (per_cpu(misaligned_access_speed, cpu) != RISCV_HWPROBE_MISALIGNED_SCALAR_UNKNOWN)
+		return 0;
+
+	ret = compare_unaligned_access(__riscv_copy_words_unaligned,
+				       __riscv_copy_bytes_unaligned,
+				       buf, "scalar");
+	if (ret < 0)
+		return 0;
 
 	/*
 	 * Set the value of fast_misaligned_access of a CPU. These operations
 	 * are atomic to avoid race conditions.
 	 */
-	if (speed == RISCV_HWPROBE_MISALIGNED_SCALAR_FAST)
+	if (ret) {
+		per_cpu(misaligned_access_speed, cpu) = RISCV_HWPROBE_MISALIGNED_SCALAR_FAST;
 		cpumask_set_cpu(cpu, &fast_misaligned_access);
-	else
+	} else {
+		per_cpu(misaligned_access_speed, cpu) = RISCV_HWPROBE_MISALIGNED_SCALAR_SLOW;
 		cpumask_clear_cpu(cpu, &fast_misaligned_access);
+	}
 
 	return 0;
 }
 
-static void __init check_unaligned_access_nonboot_cpu(void *param)
+static void __init _check_unaligned_access(void *param)
 {
 	unsigned int cpu = smp_processor_id();
 	struct page **pages = param;
 
-	if (smp_processor_id() != 0)
-		check_unaligned_access(pages[cpu]);
+	check_unaligned_access(pages[cpu]);
 }
 
 /* Measure unaligned access speed on all CPUs present at boot in parallel. */
@@ -158,11 +174,7 @@ static void __init check_unaligned_access_speed_all_cpus(void)
 		}
 	}
 
-	/* Check everybody except 0, who stays behind to tend jiffies. */
-	on_each_cpu(check_unaligned_access_nonboot_cpu, bufs, 1);
-
-	/* Check core 0. */
-	smp_call_on_cpu(0, check_unaligned_access, bufs[0], true);
+	on_each_cpu(_check_unaligned_access, bufs, 1);
 
 out:
 	for_each_cpu(cpu, cpu_online_mask) {
@@ -281,15 +293,8 @@ static int riscv_offline_cpu(unsigned int cpu)
 static void check_vector_unaligned_access(struct work_struct *work __always_unused)
 {
 	int cpu = smp_processor_id();
-	u64 start_cycles, end_cycles;
-	u64 word_cycles;
-	u64 byte_cycles;
-	int ratio;
-	unsigned long start_jiffies, now;
 	struct page *page;
-	void *dst;
-	void *src;
-	long speed = RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW;
+	int ret;
 
 	if (per_cpu(vector_misaligned_access, cpu) != RISCV_HWPROBE_MISALIGNED_VECTOR_UNKNOWN)
 		return;
@@ -300,76 +305,20 @@ static void check_vector_unaligned_access(struct work_struct *work __always_unus
 		return;
 	}
 
-	/* Make an unaligned destination buffer. */
-	dst = (void *)((unsigned long)page_address(page) | 0x1);
-	/* Unalign src as well, but differently (off by 1 + 2 = 3). */
-	src = dst + (MISALIGNED_BUFFER_SIZE / 2);
-	src += 2;
-	word_cycles = -1ULL;
-
-	/* Do a warmup. */
 	kernel_vector_begin();
-	__riscv_copy_vec_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
 
-	start_jiffies = jiffies;
-	while ((now = jiffies) == start_jiffies)
-		cpu_relax();
-
-	/*
-	 * For a fixed amount of time, repeatedly try the function, and take
-	 * the best time in cycles as the measurement.
-	 */
-	while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
-		start_cycles = get_cycles64();
-		/* Ensure the CSR read can't reorder WRT to the copy. */
-		mb();
-		__riscv_copy_vec_words_unaligned(dst, src, MISALIGNED_COPY_SIZE);
-		/* Ensure the copy ends before the end time is snapped. */
-		mb();
-		end_cycles = get_cycles64();
-		if ((end_cycles - start_cycles) < word_cycles)
-			word_cycles = end_cycles - start_cycles;
-	}
-
-	byte_cycles = -1ULL;
-	__riscv_copy_vec_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
-	start_jiffies = jiffies;
-	while ((now = jiffies) == start_jiffies)
-		cpu_relax();
-
-	while (time_before(jiffies, now + (1 << MISALIGNED_ACCESS_JIFFIES_LG2))) {
-		start_cycles = get_cycles64();
-		/* Ensure the CSR read can't reorder WRT to the copy. */
-		mb();
-		__riscv_copy_vec_bytes_unaligned(dst, src, MISALIGNED_COPY_SIZE);
-		/* Ensure the copy ends before the end time is snapped. */
-		mb();
-		end_cycles = get_cycles64();
-		if ((end_cycles - start_cycles) < byte_cycles)
-			byte_cycles = end_cycles - start_cycles;
-	}
-
+	ret = compare_unaligned_access(__riscv_copy_vec_words_unaligned,
+				       __riscv_copy_vec_bytes_unaligned,
+				       page_address(page), "vector");
 	kernel_vector_end();
 
-	/* Don't divide by zero. */
-	if (!word_cycles || !byte_cycles) {
-		pr_warn("cpu%d: rdtime lacks granularity needed to measure unaligned vector access speed\n",
-			cpu);
-
+	if (ret < 0)
 		goto free;
-	}
 
-	if (word_cycles < byte_cycles)
-		speed = RISCV_HWPROBE_MISALIGNED_VECTOR_FAST;
-
-	ratio = div_u64((byte_cycles * 100), word_cycles);
-	pr_info("cpu%d: Ratio of vector byte access time to vector unaligned word access is %d.%02d, unaligned accesses are %s\n",
-		cpu,
-		ratio / 100,
-		ratio % 100,
-		(speed ==  RISCV_HWPROBE_MISALIGNED_VECTOR_FAST) ? "fast" : "slow");
-
-	per_cpu(vector_misaligned_access, cpu) = speed;
+	if (ret)
+		per_cpu(vector_misaligned_access, cpu) = RISCV_HWPROBE_MISALIGNED_VECTOR_FAST;
+	else
+		per_cpu(vector_misaligned_access, cpu) = RISCV_HWPROBE_MISALIGNED_VECTOR_SLOW;
 
 free:
 	__free_pages(page, MISALIGNED_BUFFER_ORDER);
@@ -494,4 +443,4 @@ static int __init check_unaligned_access_all_cpus(void)
 	return 0;
 }
 
-arch_initcall(check_unaligned_access_all_cpus);
+late_initcall(check_unaligned_access_all_cpus);
diff --git a/arch/riscv/kernel/vdso_cfi/.gitignore b/arch/riscv/kernel/vdso_cfi/.gitignore
new file mode 100644
index 0000000..220b6eb
--- /dev/null
+++ b/arch/riscv/kernel/vdso_cfi/.gitignore
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-only
+# Copied source files from the main vdso directory
+*.c
+*.S
+!vdso-cfi.S
+vdso.lds
+*.tmp
+vdso-syms.S
diff --git a/arch/riscv/kernel/vdso_cfi/Makefile b/arch/riscv/kernel/vdso_cfi/Makefile
index 8ebd190..1029249 100644
--- a/arch/riscv/kernel/vdso_cfi/Makefile
+++ b/arch/riscv/kernel/vdso_cfi/Makefile
@@ -23,3 +23,6 @@
 # Include the main VDSO Makefile which contains all the build rules and sources
 # The VDSO_CFI_BUILD variable will be passed to it to enable CFI compilation
 include $(src)/Makefile
+
+# Clean rules - remove the copied source files
+clean-files += $(notdir $(vdso_c_sources)) $(notdir $(vdso_S_sources))
diff --git a/arch/riscv/kernel/vmcore_info.c b/arch/riscv/kernel/vmcore_info.c
index d5e448a..c27efce 100644
--- a/arch/riscv/kernel/vmcore_info.c
+++ b/arch/riscv/kernel/vmcore_info.c
@@ -3,6 +3,11 @@
 #include <linux/vmcore_info.h>
 #include <linux/pagemap.h>
 
+static inline u64 get_satp_value(void)
+{
+	return csr_read(CSR_SATP);
+}
+
 void arch_crash_save_vmcoreinfo(void)
 {
 	VMCOREINFO_NUMBER(phys_ram_base);
@@ -19,13 +24,8 @@ void arch_crash_save_vmcoreinfo(void)
 #endif
 #endif
 	vmcoreinfo_append_str("NUMBER(KERNEL_LINK_ADDR)=0x%lx\n", KERNEL_LINK_ADDR);
-#ifdef CONFIG_XIP_KERNEL
-	/* TODO: Communicate with crash-utility developers on the information to
-	 * export. The XIP case is more complicated, because the virtual-physical
-	 * address offset depends on whether the address is in ROM or in RAM.
-	 */
-#else
 	vmcoreinfo_append_str("NUMBER(va_kernel_pa_offset)=0x%lx\n",
 						kernel_map.va_kernel_pa_offset);
-#endif
+	vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());
+	vmcoreinfo_append_str("NUMBER(satp)=0x%llx\n", get_satp_value());
 }
diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
index 997f9eb..1f4f849 100644
--- a/arch/riscv/kernel/vmlinux.lds.S
+++ b/arch/riscv/kernel/vmlinux.lds.S
@@ -7,10 +7,6 @@
 #define RO_EXCEPTION_TABLE_ALIGN	4
 #define RUNTIME_DISCARD_EXIT
 
-#ifdef CONFIG_XIP_KERNEL
-#include "vmlinux-xip.lds.S"
-#else
-
 #include <asm/pgtable.h>
 #define LOAD_OFFSET KERNEL_LINK_ADDR
 
@@ -176,4 +172,3 @@
 
 	DISCARDS
 }
-#endif /* CONFIG_XIP_KERNEL */
diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c
index 439c20c..993b25e 100644
--- a/arch/riscv/kvm/tlb.c
+++ b/arch/riscv/kvm/tlb.c
@@ -182,7 +182,7 @@ void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu)
 
 	/*
 	 * Flush VS-stage TLB entries for implementation where VS-stage
-	 * TLB does not cahce guest physical address and VMID.
+	 * TLB does not cache guest physical address and VMID.
 	 */
 	if (static_branch_unlikely(&kvm_riscv_vsstage_tlb_no_gpa))
 		kvm_riscv_local_hfence_vvma_all(vmid);
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 18ef07b..a935ed9 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -694,7 +694,7 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base,
 				pmc->counter_val += perf_event_read_value(pmc->perf_event,
 									  &enabled, &running);
 			/*
-			 * The counter and overflow indicies in the snapshot region are w.r.to
+			 * The counter and overflow indices in the snapshot region are w.r.to
 			 * cbase. Modify the set bit in the counter mask instead of the pmc_index
 			 * which indicates the absolute counter index.
 			 */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index e220c35..6f767b2 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -7,6 +7,9 @@
 lib-y			+= strcmp.o
 lib-y			+= strlen.o
 lib-y			+= strncmp.o
+lib-y			+= strnlen.o
+lib-y			+= strchr.o
+lib-y			+= strrchr.o
 endif
 lib-y			+= csum.o
 ifeq ($(CONFIG_MMU), y)
diff --git a/arch/riscv/lib/csum.c b/arch/riscv/lib/csum.c
index 75bd0ab..5d43797 100644
--- a/arch/riscv/lib/csum.c
+++ b/arch/riscv/lib/csum.c
@@ -269,7 +269,7 @@ unsigned int do_csum(const unsigned char *buff, int len)
 	 * on machines with fast misaligned accesses.
 	 *
 	 * There is some duplicate code between the "with_alignment" and
-	 * "no_alignment" implmentations, but the overlap is too awkward to be
+	 * "no_alignment" implementations, but the overlap is too awkward to be
 	 * able to fit in one function without introducing multiple static
 	 * branches. The largest chunk of overlap was delegated into the
 	 * do_csum_common function.
diff --git a/arch/riscv/lib/memmove.S b/arch/riscv/lib/memmove.S
index cb3e2e7..410e598 100644
--- a/arch/riscv/lib/memmove.S
+++ b/arch/riscv/lib/memmove.S
@@ -40,8 +40,8 @@
 	 *   Both Copy Modes: t1 - Temporary for load-store
 	 *   Both Copy Modes: t2 - Temporary for load-store
 	 *   Both Copy Modes: a5 - dest to src alignment offset
-	 *   Both Copy Modes: a6 - Shift ammount
-	 *   Both Copy Modes: a7 - Inverse Shift ammount
+	 *   Both Copy Modes: a6 - Shift amount
+	 *   Both Copy Modes: a7 - Inverse Shift amount
 	 *   Both Copy Modes: a2 - Alternate breakpoint for unrolled loops
 	 */
 
diff --git a/arch/riscv/lib/strchr.S b/arch/riscv/lib/strchr.S
new file mode 100644
index 0000000..48c3a9d
--- /dev/null
+++ b/arch/riscv/lib/strchr.S
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Copyright (C) 2025 Feng Jiang <jiangfeng@kylinos.cn>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/* char *strchr(const char *s, int c) */
+SYM_FUNC_START(strchr)
+	/*
+	 * Parameters
+	 *   a0 - The string to be searched
+	 *   a1 - The character to search for
+	 *
+	 * Returns
+	 *   a0 - Address of first occurrence of 'c' or 0
+	 *
+	 * Clobbers
+	 *   t0
+	 */
+	andi	a1, a1, 0xff
+1:
+	lbu	t0, 0(a0)
+	beq	t0, a1, 2f
+	addi	a0, a0, 1
+	bnez	t0, 1b
+	li	a0, 0
+2:
+	ret
+SYM_FUNC_END(strchr)
+
+SYM_FUNC_ALIAS_WEAK(__pi_strchr, strchr)
+EXPORT_SYMBOL(strchr)
diff --git a/arch/riscv/lib/strnlen.S b/arch/riscv/lib/strnlen.S
new file mode 100644
index 0000000..53afa7b
--- /dev/null
+++ b/arch/riscv/lib/strnlen.S
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Base on arch/riscv/lib/strlen.S
+ *
+ * Copyright (C) Feng Jiang <jiangfeng@kylinos.cn>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+#include <asm/alternative-macros.h>
+#include <asm/hwcap.h>
+
+/* size_t strnlen(const char *s, size_t count) */
+SYM_FUNC_START(strnlen)
+
+	__ALTERNATIVE_CFG("nop", "j strnlen_zbb", 0, RISCV_ISA_EXT_ZBB,
+		IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB))
+
+
+	/*
+	 * Returns
+	 *   a0 - String length
+	 *
+	 * Parameters
+	 *   a0 - String to measure
+	 *   a1 - Max length of string
+	 *
+	 * Clobbers
+	 *   t0, t1, t2
+	 */
+	addi	t1, a0, -1
+	add	t2, a0, a1
+1:
+	addi	t1, t1, 1
+	beq	t1, t2, 2f
+	lbu	t0, 0(t1)
+	bnez	t0, 1b
+2:
+	sub	a0, t1, a0
+	ret
+
+
+/*
+ * Variant of strnlen using the ZBB extension if available
+ */
+#if defined(CONFIG_RISCV_ISA_ZBB) && defined(CONFIG_TOOLCHAIN_HAS_ZBB)
+strnlen_zbb:
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+# define CZ	clz
+# define SHIFT	sll
+#else
+# define CZ	ctz
+# define SHIFT	srl
+#endif
+
+.option push
+.option arch,+zbb
+
+	/*
+	 * Returns
+	 *   a0 - String length
+	 *
+	 * Parameters
+	 *   a0 - String to measure
+	 *   a1 - Max length of string
+	 *
+	 * Clobbers
+	 *   t0, t1, t2, t3, t4
+	 */
+
+	/* If maxlen is 0, return 0. */
+	beqz	a1, 3f
+
+	/* Number of irrelevant bytes in the first word. */
+	andi	t2, a0, SZREG-1
+
+	/* Align pointer. */
+	andi	t0, a0, -SZREG
+
+	li	t3, SZREG
+	sub	t3, t3, t2
+	slli	t2, t2, 3
+
+	/* Aligned boundary. */
+	add	t4, a0, a1
+	andi	t4, t4, -SZREG
+
+	/* Get the first word.  */
+	REG_L	t1, 0(t0)
+
+	/*
+	 * Shift away the partial data we loaded to remove the irrelevant bytes
+	 * preceding the string with the effect of adding NUL bytes at the
+	 * end of the string's first word.
+	 */
+	SHIFT	t1, t1, t2
+
+	/* Convert non-NUL into 0xff and NUL into 0x00. */
+	orc.b	t1, t1
+
+	/* Convert non-NUL into 0x00 and NUL into 0xff. */
+	not	t1, t1
+
+	/*
+	 * Search for the first set bit (corresponding to a NUL byte in the
+	 * original chunk).
+	 */
+	CZ	t1, t1
+
+	/*
+	 * The first chunk is special: compare against the number
+	 * of valid bytes in this chunk.
+	 */
+	srli	a0, t1, 3
+
+	/* Limit the result by maxlen. */
+	minu	a0, a0, a1
+
+	bgtu	t3, a0, 2f
+
+	/* Prepare for the word comparison loop. */
+	addi	t2, t0, SZREG
+	li	t3, -1
+
+	/*
+	 * Our critical loop is 4 instructions and processes data in
+	 * 4 byte or 8 byte chunks.
+	 */
+	.p2align 3
+1:
+	REG_L	t1, SZREG(t0)
+	addi	t0, t0, SZREG
+	orc.b	t1, t1
+	bgeu	t0, t4, 4f
+	beq	t1, t3, 1b
+4:
+	not	t1, t1
+	CZ	t1, t1
+	srli	t1, t1, 3
+
+	/* Get number of processed bytes. */
+	sub	t2, t0, t2
+
+	/* Add number of characters in the first word.  */
+	add	a0, a0, t2
+
+	/* Add number of characters in the last word.  */
+	add	a0, a0, t1
+
+	/* Ensure the final result does not exceed maxlen. */
+	minu	a0, a0, a1
+2:
+	ret
+3:
+	mv	a0, a1
+	ret
+
+.option pop
+#endif
+SYM_FUNC_END(strnlen)
+SYM_FUNC_ALIAS(__pi_strnlen, strnlen)
+EXPORT_SYMBOL(strnlen)
diff --git a/arch/riscv/lib/strrchr.S b/arch/riscv/lib/strrchr.S
new file mode 100644
index 0000000..ac58b20
--- /dev/null
+++ b/arch/riscv/lib/strrchr.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Copyright (C) 2025 Feng Jiang <jiangfeng@kylinos.cn>
+ */
+
+#include <linux/linkage.h>
+#include <asm/asm.h>
+
+/* char *strrchr(const char *s, int c) */
+SYM_FUNC_START(strrchr)
+	/*
+	 * Parameters
+	 *	a0 - The string to be searched
+	 *	a1 - The character to seaerch for
+	 *
+	 * Returns
+	 *	a0 - Address of last occurrence of 'c' or 0
+	 *
+	 * Clobbers
+	 *	t0, t1
+	 */
+	andi	a1, a1, 0xff
+	mv	t1, a0
+	li	a0, 0
+1:
+	lbu	t0, 0(t1)
+	bne	t0, a1, 2f
+	mv	a0, t1
+2:
+	addi	t1, t1, 1
+	bnez	t0, 1b
+	ret
+SYM_FUNC_END(strrchr)
+
+SYM_FUNC_ALIAS_WEAK(__pi_strrchr, strrchr)
+EXPORT_SYMBOL(strrchr)
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index d83a612..f8ead7c 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -29,7 +29,7 @@ void flush_icache_all(void)
 	 * Make sure all previous writes to the D$ are ordered before making
 	 * the IPI. The RISC-V spec states that a hart must execute a data fence
 	 * before triggering a remote fence.i in order to make the modification
-	 * visable for remote harts.
+	 * visible for remote harts.
 	 *
 	 * IPIs on RISC-V are triggered by MMIO writes to either CLINT or
 	 * S-IMSIC, so the fence ensures previous data writes "happen before"
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index b5c5095..decd7df4 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -41,20 +41,17 @@ u64 new_vmalloc[NR_CPUS / sizeof(u64) + 1];
 
 struct kernel_mapping kernel_map __ro_after_init;
 EXPORT_SYMBOL(kernel_map);
-#ifdef CONFIG_XIP_KERNEL
-#define kernel_map	(*(struct kernel_mapping *)XIP_FIXUP(&kernel_map))
-#endif
 
 #ifdef CONFIG_64BIT
-u64 satp_mode __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL) ? SATP_MODE_57 : SATP_MODE_39;
+u64 satp_mode __ro_after_init = SATP_MODE_57;
 #else
 u64 satp_mode __ro_after_init = SATP_MODE_32;
 #endif
 EXPORT_SYMBOL(satp_mode);
 
 #ifdef CONFIG_64BIT
-bool pgtable_l4_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
-bool pgtable_l5_enabled __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL);
+bool pgtable_l4_enabled __ro_after_init = true;
+bool pgtable_l5_enabled __ro_after_init = true;
 EXPORT_SYMBOL(pgtable_l4_enabled);
 EXPORT_SYMBOL(pgtable_l5_enabled);
 #endif
@@ -190,9 +187,6 @@ void __init arch_mm_preinit(void)
 
 /* Limit the memory size via mem. */
 static phys_addr_t memory_limit;
-#ifdef CONFIG_XIP_KERNEL
-#define memory_limit	(*(phys_addr_t *)XIP_FIXUP(&memory_limit))
-#endif /* CONFIG_XIP_KERNEL */
 
 static int __init early_mem(char *p)
 {
@@ -216,10 +210,7 @@ static void __init setup_bootmem(void)
 	phys_addr_t max_mapped_addr;
 	phys_addr_t phys_ram_end, vmlinux_start;
 
-	if (IS_ENABLED(CONFIG_XIP_KERNEL))
-		vmlinux_start = __pa_symbol(&_sdata);
-	else
-		vmlinux_start = __pa_symbol(&_start);
+	vmlinux_start = __pa_symbol(&_start);
 
 	memblock_enforce_memory_limit(memory_limit);
 
@@ -239,12 +230,10 @@ static void __init setup_bootmem(void)
 	 * 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)) {
-		phys_ram_base = memblock_start_of_DRAM() & PMD_MASK;
+	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;
+	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
@@ -357,13 +346,6 @@ static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
 
 pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
 
-#ifdef CONFIG_XIP_KERNEL
-#define pt_ops			(*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
-#define trampoline_pg_dir      ((pgd_t *)XIP_FIXUP(trampoline_pg_dir))
-#define fixmap_pte             ((pte_t *)XIP_FIXUP(fixmap_pte))
-#define early_pg_dir           ((pgd_t *)XIP_FIXUP(early_pg_dir))
-#endif /* CONFIG_XIP_KERNEL */
-
 static const pgprot_t protection_map[16] = {
 	[VM_NONE]					= PAGE_NONE,
 	[VM_READ]					= PAGE_READ,
@@ -460,32 +442,14 @@ static pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss;
 static pmd_t fixmap_pmd[PTRS_PER_PMD] __page_aligned_bss;
 static pmd_t early_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
 
-#ifdef CONFIG_XIP_KERNEL
-#define trampoline_pmd ((pmd_t *)XIP_FIXUP(trampoline_pmd))
-#define fixmap_pmd     ((pmd_t *)XIP_FIXUP(fixmap_pmd))
-#define early_pmd      ((pmd_t *)XIP_FIXUP(early_pmd))
-#endif /* CONFIG_XIP_KERNEL */
-
 static p4d_t trampoline_p4d[PTRS_PER_P4D] __page_aligned_bss;
 static p4d_t fixmap_p4d[PTRS_PER_P4D] __page_aligned_bss;
 static p4d_t early_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
 
-#ifdef CONFIG_XIP_KERNEL
-#define trampoline_p4d ((p4d_t *)XIP_FIXUP(trampoline_p4d))
-#define fixmap_p4d     ((p4d_t *)XIP_FIXUP(fixmap_p4d))
-#define early_p4d      ((p4d_t *)XIP_FIXUP(early_p4d))
-#endif /* CONFIG_XIP_KERNEL */
-
 static pud_t trampoline_pud[PTRS_PER_PUD] __page_aligned_bss;
 static pud_t fixmap_pud[PTRS_PER_PUD] __page_aligned_bss;
 static pud_t early_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
 
-#ifdef CONFIG_XIP_KERNEL
-#define trampoline_pud ((pud_t *)XIP_FIXUP(trampoline_pud))
-#define fixmap_pud     ((pud_t *)XIP_FIXUP(fixmap_pud))
-#define early_pud      ((pud_t *)XIP_FIXUP(early_pud))
-#endif /* CONFIG_XIP_KERNEL */
-
 static pmd_t *__init get_pmd_virt_early(phys_addr_t pa)
 {
 	/* Before MMU is enabled */
@@ -756,21 +720,6 @@ static uintptr_t __meminit best_map_size(phys_addr_t pa, uintptr_t va, phys_addr
 	return PAGE_SIZE;
 }
 
-#ifdef CONFIG_XIP_KERNEL
-#define phys_ram_base  (*(phys_addr_t *)XIP_FIXUP(&phys_ram_base))
-extern char _xiprom[], _exiprom[], __data_loc;
-
-/* called from head.S with MMU off */
-asmlinkage void __init __copy_data(void)
-{
-	void *from = (void *)(&__data_loc);
-	void *to = (void *)CONFIG_PHYS_RAM_BASE;
-	size_t sz = (size_t)((uintptr_t)(&_end) - (uintptr_t)(&_sdata));
-
-	memcpy(to, from, sz);
-}
-#endif
-
 #ifdef CONFIG_STRICT_KERNEL_RWX
 static __meminit pgprot_t pgprot_from_va(uintptr_t va)
 {
@@ -806,7 +755,7 @@ static __meminit pgprot_t pgprot_from_va(uintptr_t va)
 }
 #endif /* CONFIG_STRICT_KERNEL_RWX */
 
-#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
+#if defined(CONFIG_64BIT)
 u64 __pi_set_satp_mode_from_cmdline(uintptr_t dtb_pa);
 u64 __pi_set_satp_mode_from_fdt(uintptr_t dtb_pa);
 
@@ -931,28 +880,6 @@ static __init void set_satp_mode(uintptr_t dtb_pa)
 #error "setup_vm() is called from head.S before relocate so it should not use absolute addressing."
 #endif
 
-#ifdef CONFIG_XIP_KERNEL
-static void __init create_kernel_page_table(pgd_t *pgdir,
-					    __always_unused bool early)
-{
-	uintptr_t va, start_va, end_va;
-
-	/* Map the flash resident part */
-	end_va = kernel_map.virt_addr + kernel_map.xiprom_sz;
-	for (va = kernel_map.virt_addr; va < end_va; va += PMD_SIZE)
-		create_pgd_mapping(pgdir, va,
-				   kernel_map.xiprom + (va - kernel_map.virt_addr),
-				   PMD_SIZE, PAGE_KERNEL_EXEC);
-
-	/* Map the data in RAM */
-	start_va = kernel_map.virt_addr + (uintptr_t)&_sdata - (uintptr_t)&_start;
-	end_va = kernel_map.virt_addr + kernel_map.size;
-	for (va = start_va; va < end_va; va += PMD_SIZE)
-		create_pgd_mapping(pgdir, va,
-				   kernel_map.phys_addr + (va - start_va),
-				   PMD_SIZE, PAGE_KERNEL);
-}
-#else
 static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
 {
 	uintptr_t va, end_va;
@@ -965,7 +892,6 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
 				   early ?
 					PAGE_KERNEL_EXEC : pgprot_from_va(va));
 }
-#endif
 
 /*
  * Setup a 4MB mapping that encompasses the device tree: for 64-bit kernel,
@@ -1075,11 +1001,6 @@ static int __init print_nokaslr(char *p)
 	return 0;
 }
 early_param("nokaslr", print_nokaslr);
-
-unsigned long kaslr_offset(void)
-{
-	return kernel_map.virt_offset;
-}
 #endif
 
 asmlinkage void __init setup_vm(uintptr_t dtb_pa)
@@ -1107,27 +1028,11 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 
 	kernel_map.virt_addr = KERNEL_LINK_ADDR + kernel_map.virt_offset;
 
-#ifdef CONFIG_XIP_KERNEL
-	kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR;
-	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)(&_start);
-
-	kernel_map.va_kernel_xip_text_pa_offset = kernel_map.virt_addr - kernel_map.xiprom;
-	kernel_map.va_kernel_xip_data_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr
-						+ (uintptr_t)&_sdata - (uintptr_t)&_start;
-#else
 	kernel_map.phys_addr = (uintptr_t)(&_start);
 	kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr;
 	kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr;
-#endif
 
-#if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
+#if defined(CONFIG_64BIT)
 	set_satp_mode(dtb_pa);
 	set_mmap_rnd_bits_max();
 #endif
@@ -1200,13 +1105,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 	if (pgtable_l4_enabled)
 		create_pud_mapping(trampoline_pud, kernel_map.virt_addr,
 				   (uintptr_t)trampoline_pmd, PUD_SIZE, PAGE_TABLE);
-#ifdef CONFIG_XIP_KERNEL
-	create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
-			   kernel_map.xiprom, PMD_SIZE, PAGE_KERNEL_EXEC);
-#else
 	create_pmd_mapping(trampoline_pmd, kernel_map.virt_addr,
 			   kernel_map.phys_addr, PMD_SIZE, PAGE_KERNEL_EXEC);
-#endif
 #else
 	/* Setup trampoline PGD */
 	create_pgd_mapping(trampoline_pg_dir, kernel_map.virt_addr,
@@ -1450,6 +1350,8 @@ int __meminit vmemmap_check_pmd(pmd_t *pmdp, int node,
 int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
 			       struct vmem_altmap *altmap)
 {
+	WARN_ON((start < VMEMMAP_START) || (end > VMEMMAP_END));
+
 	/*
 	 * Note that SPARSEMEM_VMEMMAP is only selected for rv64 and that we
 	 * can't use hugepage mappings for 2-level page table because in case of
diff --git a/arch/riscv/mm/physaddr.c b/arch/riscv/mm/physaddr.c
index 559d291..b1836e9 100644
--- a/arch/riscv/mm/physaddr.c
+++ b/arch/riscv/mm/physaddr.c
@@ -9,7 +9,7 @@
 phys_addr_t __virt_to_phys(unsigned long x)
 {
 	/*
-	 * Boundary checking aginst the kernel linear mapping space.
+	 * Boundary checking against the kernel linear mapping space.
 	 */
 	WARN(!is_linear_mapping(x) && !is_kernel_mapping(x),
 	     "virt_to_phys used for non-linear address: %p (%pS)\n",
@@ -25,7 +25,7 @@ phys_addr_t __phys_addr_symbol(unsigned long x)
 	unsigned long kernel_end = kernel_start + kernel_map.size;
 
 	/*
-	 * Boundary checking aginst the kernel image mapping.
+	 * Boundary checking against the kernel image mapping.
 	 * __pa_symbol should only be used on kernel symbol addresses.
 	 */
 	VIRTUAL_BUG_ON(x < kernel_start || x > kernel_end);
diff --git a/arch/riscv/purgatory/Makefile b/arch/riscv/purgatory/Makefile
index 530e497..b0358a7 100644
--- a/arch/riscv/purgatory/Makefile
+++ b/arch/riscv/purgatory/Makefile
@@ -2,7 +2,7 @@
 
 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
+purgatory-y += strcmp.o strlen.o strncmp.o strnlen.o strchr.o strrchr.o
 endif
 
 targets += $(purgatory-y)
@@ -32,6 +32,15 @@
 $(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
 	$(call if_changed_rule,cc_o_c)
 
+$(obj)/strnlen.o: $(srctree)/arch/riscv/lib/strnlen.S FORCE
+	$(call if_changed_rule,as_o_S)
+
+$(obj)/strchr.o: $(srctree)/arch/riscv/lib/strchr.S FORCE
+	$(call if_changed_rule,as_o_S)
+
+$(obj)/strrchr.o: $(srctree)/arch/riscv/lib/strrchr.S FORCE
+	$(call if_changed_rule,as_o_S)
+
 CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
 CFLAGS_string.o := -D__DISABLE_EXPORTS
 CFLAGS_ctype.o := -D__DISABLE_EXPORTS
diff --git a/arch/riscv/purgatory/kexec-purgatory.S b/arch/riscv/purgatory/kexec-purgatory.S
index 0e91888..32c5358 100644
--- a/arch/riscv/purgatory/kexec-purgatory.S
+++ b/arch/riscv/purgatory/kexec-purgatory.S
@@ -6,9 +6,9 @@
 kexec_purgatory:
 	.globl	kexec_purgatory
 	.incbin	"arch/riscv/purgatory/purgatory.ro"
-.Lkexec_purgatroy_end:
+.Lkexec_purgatory_end:
 
 	.align	8
 kexec_purgatory_size:
 	.globl	kexec_purgatory_size
-	.quad	.Lkexec_purgatroy_end - kexec_purgatory
+	.quad	.Lkexec_purgatory_end - kexec_purgatory
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 1a555a4..ecbcbb7 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -152,6 +152,7 @@
 	select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && CC_IS_CLANG
 	select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
 	select ARCH_SUPPORTS_NUMA_BALANCING
+	select ARCH_SUPPORTS_PAGE_TABLE_CHECK
 	select ARCH_SUPPORTS_PER_VMA_LOCK
 	select ARCH_USE_BUILTIN_BSWAP
 	select ARCH_USE_CMPXCHG_LOCKREF
@@ -1023,7 +1024,7 @@
 
 config S390_MODULES_SANITY_TEST
 	def_tristate n
-	depends on KUNIT
+	depends on KUNIT && m
 	default KUNIT_ALL_TESTS
 	prompt "Enable s390 specific modules tests"
 	select S390_MODULES_SANITY_TEST_HELPERS
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 7f33434..c1dcf8b 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -440,7 +440,8 @@ static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
 	max_mappable = max(ident_map_size, MAX_DCSS_ADDR);
 	max_mappable = min(max_mappable, vmemmap_start);
 #ifdef CONFIG_RANDOMIZE_IDENTITY_BASE
-	__identity_base = round_down(vmemmap_start - max_mappable, rte_size);
+	if (kaslr_enabled())
+		__identity_base = round_down(vmemmap_start - max_mappable, rte_size);
 #endif
 	boot_debug("identity map:        0x%016lx-0x%016lx\n", __identity_base,
 		   __identity_base + ident_map_size);
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 34b5ea7..c28f9a7 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -925,3 +925,5 @@
 CONFIG_ATOMIC64_SELFTEST=y
 CONFIG_TEST_BITOPS=m
 CONFIG_TEST_BPF=m
+CONFIG_PAGE_TABLE_CHECK=y
+CONFIG_PAGE_TABLE_CHECK_ENFORCED=y
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index c0ff19d..5dcf35f 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -208,6 +208,10 @@ extern const struct attribute_group zpci_ident_attr_group;
 			    &pfip_attr_group,		 \
 			    &zpci_ident_attr_group,
 
+extern const struct attribute_group zpci_slot_attr_group;
+
+#define ARCH_PCI_SLOT_GROUPS (&zpci_slot_attr_group)
+
 extern unsigned int s390_pci_force_floating __initdata;
 extern unsigned int s390_pci_no_rid;
 
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 5899f57..b18a96f 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -12,6 +12,24 @@
  */
 #define __my_cpu_offset get_lowcore()->percpu_offset
 
+#define arch_raw_cpu_ptr(_ptr)						\
+({									\
+	unsigned long lc_percpu, tcp_ptr__;				\
+									\
+	tcp_ptr__ = (__force unsigned long)(_ptr);			\
+	lc_percpu = offsetof(struct lowcore, percpu_offset);		\
+	asm_inline volatile(						\
+	ALTERNATIVE("ag		%[__ptr__],%[offzero](%%r0)\n",		\
+		    "ag		%[__ptr__],%[offalt](%%r0)\n",		\
+		    ALT_FEATURE(MFEATURE_LOWCORE))			\
+	: [__ptr__] "+d" (tcp_ptr__)					\
+	: [offzero] "i" (lc_percpu),					\
+	  [offalt] "i" (lc_percpu + LOWCORE_ALT_ADDRESS),		\
+	  "m" (((struct lowcore *)0)->percpu_offset)			\
+	: "cc");							\
+	(TYPEOF_UNQUAL(*(_ptr)) __force __kernel *)tcp_ptr__;		\
+})
+
 /*
  * We use a compare-and-swap loop since that uses less cpu cycles than
  * disabling and enabling interrupts like the generic variant would do.
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 40a6fb1..2c6cee8 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -16,8 +16,10 @@
 #include <linux/mm_types.h>
 #include <linux/cpufeature.h>
 #include <linux/page-flags.h>
+#include <linux/page_table_check.h>
 #include <linux/radix-tree.h>
 #include <linux/atomic.h>
+#include <linux/mmap_lock.h>
 #include <asm/ctlreg.h>
 #include <asm/bug.h>
 #include <asm/page.h>
@@ -1190,6 +1192,7 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 	/* At this point the reference through the mapping is still present */
 	if (mm_is_protected(mm) && pte_present(res))
 		WARN_ON_ONCE(uv_convert_from_secure_pte(res));
+	page_table_check_pte_clear(mm, addr, res);
 	return res;
 }
 
@@ -1208,6 +1211,7 @@ static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
 	/* At this point the reference through the mapping is still present */
 	if (mm_is_protected(vma->vm_mm) && pte_present(res))
 		WARN_ON_ONCE(uv_convert_from_secure_pte(res));
+	page_table_check_pte_clear(vma->vm_mm, addr, res);
 	return res;
 }
 
@@ -1231,6 +1235,9 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
 	} else {
 		res = ptep_xchg_lazy(mm, addr, ptep, __pte(_PAGE_INVALID));
 	}
+
+	page_table_check_pte_clear(mm, addr, res);
+
 	/* Nothing to do */
 	if (!mm_is_protected(mm) || !pte_present(res))
 		return res;
@@ -1327,6 +1334,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr,
 {
 	if (pte_present(entry))
 		entry = clear_pte_bit(entry, __pgprot(_PAGE_UNUSED));
+	page_table_check_ptes_set(mm, addr, ptep, entry, nr);
 	for (;;) {
 		set_pte(ptep, entry);
 		if (--nr == 0)
@@ -1703,6 +1711,7 @@ static inline bool pmdp_clear_flush_young(struct vm_area_struct *vma,
 static inline void set_pmd_at(struct mm_struct *mm, unsigned long addr,
 			      pmd_t *pmdp, pmd_t entry)
 {
+	page_table_check_pmd_set(mm, addr, pmdp, entry);
 	set_pmd(pmdp, entry);
 }
 
@@ -1717,7 +1726,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
 static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 					    unsigned long addr, pmd_t *pmdp)
 {
-	return pmdp_xchg_direct(mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+	pmd_t pmd;
+
+	pmd = pmdp_xchg_direct(mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+	page_table_check_pmd_clear(mm, addr, pmd);
+	return pmd;
 }
 
 #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR_FULL
@@ -1725,12 +1738,17 @@ static inline pmd_t pmdp_huge_get_and_clear_full(struct vm_area_struct *vma,
 						 unsigned long addr,
 						 pmd_t *pmdp, int full)
 {
+	pmd_t pmd;
+
 	if (full) {
-		pmd_t pmd = *pmdp;
+		pmd = *pmdp;
 		set_pmd(pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+		page_table_check_pmd_clear(vma->vm_mm, addr, pmd);
 		return pmd;
 	}
-	return pmdp_xchg_lazy(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+	pmd = pmdp_xchg_lazy(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY));
+	page_table_check_pmd_clear(vma->vm_mm, addr, pmd);
+	return pmd;
 }
 
 #define __HAVE_ARCH_PMDP_HUGE_CLEAR_FLUSH
@@ -1744,11 +1762,16 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma,
 static inline pmd_t pmdp_invalidate(struct vm_area_struct *vma,
 				   unsigned long addr, pmd_t *pmdp)
 {
-	pmd_t pmd;
+	pmd_t pmd = *pmdp;
 
-	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);
+	VM_WARN_ON_ONCE(!pmd_present(pmd));
+	pmd = set_pmd_bit(pmd, __pgprot(_SEGMENT_ENTRY_INVALID));
+#ifdef CONFIG_PAGE_TABLE_CHECK
+	pmd = clear_pmd_bit(pmd, __pgprot(_SEGMENT_ENTRY_READ));
+#endif
+	page_table_check_pmd_set(vma->vm_mm, addr, pmdp, pmd);
+	pmd = pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd);
+	return pmd;
 }
 
 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
@@ -1783,6 +1806,29 @@ static inline int has_transparent_hugepage(void)
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+#ifdef CONFIG_PAGE_TABLE_CHECK
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
+{
+	VM_BUG_ON(mm == &init_mm);
+
+	return pte_present(pte);
+}
+
+static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
+{
+	VM_BUG_ON(mm == &init_mm);
+
+	return pmd_leaf(pmd) && (pmd_val(pmd) & _SEGMENT_ENTRY_READ);
+}
+
+static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
+{
+	VM_BUG_ON(mm == &init_mm);
+
+	return pud_leaf(pud);
+}
+#endif
+
 /*
  * 64 bit swap entry format:
  * A page-table entry has some bits we have to treat in a special way.
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 7c57ac9..cbf60ad 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -52,7 +52,6 @@ extern unsigned int zlib_dfltcc_support;
 #define ZLIB_DFLTCC_INFLATE_ONLY	3
 #define ZLIB_DFLTCC_FULL_DEBUG		4
 
-extern unsigned long ident_map_size;
 extern unsigned long max_mappable;
 
 /* The Write Back bit position in the physaddr is given by the SLPC PCI */
diff --git a/arch/s390/pci/pci_sysfs.c b/arch/s390/pci/pci_sysfs.c
index c2444a2..d98d97d 100644
--- a/arch/s390/pci/pci_sysfs.c
+++ b/arch/s390/pci/pci_sysfs.c
@@ -187,6 +187,17 @@ static ssize_t index_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(index);
 
+static ssize_t zpci_uid_slot_show(struct pci_slot *slot, char *buf)
+{
+	struct zpci_dev *zdev = container_of(slot->hotplug, struct zpci_dev,
+					     hotplug_slot);
+
+	return sysfs_emit(buf, "0x%x\n", zdev->uid);
+}
+
+static struct pci_slot_attribute zpci_slot_attr_uid =
+	__ATTR(uid, 0444, zpci_uid_slot_show, NULL);
+
 static umode_t zpci_index_is_visible(struct kobject *kobj,
 				     struct attribute *attr, int n)
 {
@@ -243,6 +254,15 @@ const struct attribute_group pfip_attr_group = {
 	.attrs = pfip_attrs,
 };
 
+static struct attribute *zpci_slot_attrs[] = {
+	&zpci_slot_attr_uid.attr,
+	NULL,
+};
+
+const struct attribute_group zpci_slot_attr_group = {
+	.attrs = zpci_slot_attrs,
+};
+
 static struct attribute *clp_fw_attrs[] = {
 	&uid_checking_attr.attr,
 	NULL,
diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig
index dd58797..b31bf17 100644
--- a/arch/sh/configs/dreamcast_defconfig
+++ b/arch/sh/configs/dreamcast_defconfig
@@ -50,7 +50,6 @@
 CONFIG_WATCHDOG=y
 CONFIG_SH_WDT=y
 CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_PVR2=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FONTS=y
diff --git a/arch/sh/configs/hp6xx_defconfig b/arch/sh/configs/hp6xx_defconfig
index 04a9fcb..b6116a2 100644
--- a/arch/sh/configs/hp6xx_defconfig
+++ b/arch/sh/configs/hp6xx_defconfig
@@ -35,7 +35,6 @@
 CONFIG_LEGACY_PTY_COUNT=64
 # CONFIG_HWMON is not set
 CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_HIT=y
 CONFIG_FB_SH_MOBILE_LCDC=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
diff --git a/arch/sh/configs/se7343_defconfig b/arch/sh/configs/se7343_defconfig
index 2d4d1f9..b3ce8a5 100644
--- a/arch/sh/configs/se7343_defconfig
+++ b/arch/sh/configs/se7343_defconfig
@@ -57,7 +57,6 @@
 CONFIG_I2C_SH_MOBILE=y
 # CONFIG_HWMON is not set
 CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_SOUND=y
 CONFIG_SND=y
diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig
index 13fa6a5..9e96b00 100644
--- a/arch/sh/configs/se7780_defconfig
+++ b/arch/sh/configs/se7780_defconfig
@@ -60,7 +60,6 @@
 # CONFIG_HW_RANDOM is not set
 CONFIG_THERMAL=y
 CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_SH_MOBILE_LCDC=m
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
index 48ddbc5..ca73442 100644
--- a/arch/sh/drivers/platform_early.c
+++ b/arch/sh/drivers/platform_early.c
@@ -1,4 +1,4 @@
-// SPDX--License-Identifier: GPL-2.0
+// SPDX-License-Identifier: GPL-2.0
 
 #include <asm/platform_early.h>
 #include <linux/mod_devicetable.h>
diff --git a/arch/sh/include/asm/platform_early.h b/arch/sh/include/asm/platform_early.h
index fc80213..00b6e6d 100644
--- a/arch/sh/include/asm/platform_early.h
+++ b/arch/sh/include/asm/platform_early.h
@@ -1,4 +1,4 @@
-/* SPDX--License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0 */
 
 #ifndef __PLATFORM_EARLY__
 #define __PLATFORM_EARLY__
diff --git a/arch/sh/include/cpu-sh3/cpu/dac.h b/arch/sh/include/cpu-sh3/cpu/dac.h
index fd02331..323ec85 100644
--- a/arch/sh/include/cpu-sh3/cpu/dac.h
+++ b/arch/sh/include/cpu-sh3/cpu/dac.h
@@ -2,6 +2,8 @@
 #ifndef __ASM_CPU_SH3_DAC_H
 #define __ASM_CPU_SH3_DAC_H
 
+#include <linux/io.h>
+
 /*
  * Copyright (C) 2003  Andriy Skulysh
  */
diff --git a/arch/sh/include/uapi/asm/auxvec.h b/arch/sh/include/uapi/asm/auxvec.h
index 8eb47ed..63fcc39 100644
--- a/arch/sh/include/uapi/asm/auxvec.h
+++ b/arch/sh/include/uapi/asm/auxvec.h
@@ -13,14 +13,10 @@
  */
 #define AT_FPUCW		18	/* Used FPU control word.  */
 
-#if defined(CONFIG_VSYSCALL) || !defined(__KERNEL__)
 /*
- * Only define this in the vsyscall case, the entry point to
- * the vsyscall page gets placed here. The kernel will attempt
- * to build a gate VMA we don't care about otherwise..
+ * The entry point to the vsyscall page gets placed here.
  */
 #define AT_SYSINFO_EHDR		33
-#endif
 
 /*
  * More complete cache descriptions than AT_[DIU]CACHEBSIZE.  If the
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 30f171b..ecd6c8a 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -183,14 +183,12 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size
 static void __init mdesc_memblock_free(struct mdesc_handle *hp)
 {
 	unsigned int alloc_size;
-	unsigned long start;
 
 	BUG_ON(refcount_read(&hp->refcnt) != 0);
 	BUG_ON(!list_empty(&hp->list));
 
 	alloc_size = PAGE_ALIGN(hp->handle_size);
-	start = __pa(hp);
-	memblock_free_late(start, alloc_size);
+	memblock_free(hp, alloc_size);
 }
 
 static struct mdesc_mem_ops memblock_mdesc_ops = {
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 098cda4..d9541d1 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -11,7 +11,9 @@
 	select ARCH_HAS_CACHE_LINE_SIZE
 	select ARCH_HAS_CPU_FINALIZE_INIT
 	select ARCH_HAS_FORTIFY_SOURCE
-	select ARCH_HAS_GCOV_PROFILE_ALL
+	# Clang 20 & 21 miscompute __builtin_object_size() under -fprofile-arcs
+	# on 32-bit, causing spurious compile-time errors in check_copy_size().
+	select ARCH_HAS_GCOV_PROFILE_ALL if !(!64BIT && CLANG_VERSION >= 200000 && CLANG_VERSION < 220100)
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_STRNCPY_FROM_USER
 	select ARCH_HAS_STRNLEN_USER
diff --git a/arch/um/configs/x86_64_defconfig b/arch/um/configs/x86_64_defconfig
index cf309c5..af6ff78 100644
--- a/arch/um/configs/x86_64_defconfig
+++ b/arch/um/configs/x86_64_defconfig
@@ -60,5 +60,4 @@
 CONFIG_TMPFS=y
 CONFIG_NLS=y
 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
-CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 29b4658..dc1d1bc 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -15,6 +15,12 @@
 #include "cow.h"
 #include "cow_sys.h"
 
+/*
+ * arch/um/Makefile remaps strrchr to kernel_strrchr; call the kernel
+ * name directly to avoid glibc >= 2.43's C23 strrchr macro.
+ */
+char *kernel_strrchr(const char *, int);
+
 #define PATH_LEN_V1 256
 
 /* unsigned time_t works until year 2106 */
@@ -153,7 +159,7 @@ static int absolutize(char *to, int size, char *from)
 			   errno);
 		return -1;
 	}
-	slash = strrchr(from, '/');
+	slash = kernel_strrchr(from, '/');
 	if (slash != NULL) {
 		*slash = '\0';
 		if (chdir(from)) {
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 19e0608..88ea843 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -112,13 +112,12 @@ static inline int pte_none(pte_t pte)
  */
 static inline int pte_read(pte_t pte)
 {
-	return((pte_get_bits(pte, _PAGE_USER)) &&
-	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
+	return !pte_get_bits(pte, _PAGE_PROTNONE);
 }
 
-static inline int pte_exec(pte_t pte){
-	return((pte_get_bits(pte, _PAGE_USER)) &&
-	       !(pte_get_bits(pte, _PAGE_PROTNONE)));
+static inline int pte_exec(pte_t pte)
+{
+	return !pte_get_bits(pte, _PAGE_PROTNONE);
 }
 
 static inline int pte_write(pte_t pte)
diff --git a/arch/um/kernel/skas/stub.c b/arch/um/kernel/skas/stub.c
index 67cab46..e09216a 100644
--- a/arch/um/kernel/skas/stub.c
+++ b/arch/um/kernel/skas/stub.c
@@ -146,7 +146,7 @@ stub_signal_interrupt(int sig, siginfo_t *info, void *p)
 		/* Receive the FDs */
 		num_fds = 0;
 		fd_msg = msghdr.msg_control;
-		fd_map = (void *)&CMSG_DATA(fd_msg);
+		fd_map = (void *)CMSG_DATA(fd_msg);
 		if (res == iov.iov_len && msghdr.msg_controllen > sizeof(struct cmsghdr))
 			num_fds = (fd_msg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
 
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 198269e..caef1de 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -170,8 +170,8 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
 	char **to_ptr = arg, *to = *to_ptr;
 	int n;
 
-	strncpy(to, (void *) from, len);
-	n = strnlen(to, len);
+	n = strnlen((void *) from, len);
+	memcpy_and_pad(to, len, (void *) from, n, 0);
 	*to_ptr += n;
 
 	if (n < len)
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 39608cc..1f17571 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -29,10 +29,9 @@ static int kern_map(struct mm_id *mm_idp,
 		    unsigned long virt, unsigned long len, int prot,
 		    int phys_fd, unsigned long long offset)
 {
-	/* TODO: Why is executable needed to be always set in the kernel? */
 	return os_map_memory((void *)virt, phys_fd, offset, len,
 			     prot & UM_PROT_READ, prot & UM_PROT_WRITE,
-			     1);
+			     prot & UM_PROT_EXEC);
 }
 
 static int kern_unmap(struct mm_id *mm_idp,
@@ -165,6 +164,7 @@ int um_tlb_sync(struct mm_struct *mm)
 	unsigned long addr, next;
 	int ret = 0;
 
+	guard(spinlock_irqsave)(&mm->page_table_lock);
 	guard(spinlock_irqsave)(&mm->context.sync_tlb_lock);
 
 	if (mm->context.sync_tlb_range_to == 0)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 99bb521..f3f7cb0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1885,6 +1885,7 @@
 	bool "X86 userspace shadow stack"
 	depends on AS_WRUSS
 	depends on X86_64
+	depends on PER_VMA_LOCK
 	select ARCH_USES_HIGH_VMA_FLAGS
 	select ARCH_HAS_USER_SHADOW_STACK
 	select X86_CET
diff --git a/arch/x86/Makefile.um b/arch/x86/Makefile.um
index c86cbd9..19c13af 100644
--- a/arch/x86/Makefile.um
+++ b/arch/x86/Makefile.um
@@ -60,4 +60,6 @@
 LINK-$(CONFIG_LD_SCRIPT_DYN_RPATH) += -Wl,-rpath,/lib64
 LINK-y += -m64
 
+vdso-install-y += arch/x86/um/vdso/vdso.so.dbg
+
 endif
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 13e3e9a..2187e9c 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -1672,17 +1672,17 @@ static inline bool arch_has_hw_nonleaf_pmd_young(void)
 #endif
 
 #ifdef CONFIG_PAGE_TABLE_CHECK
-static inline bool pte_user_accessible_page(pte_t pte, unsigned long addr)
+static inline bool pte_user_accessible_page(struct mm_struct *mm, unsigned long addr, pte_t pte)
 {
 	return (pte_val(pte) & _PAGE_PRESENT) && (pte_val(pte) & _PAGE_USER);
 }
 
-static inline bool pmd_user_accessible_page(pmd_t pmd, unsigned long addr)
+static inline bool pmd_user_accessible_page(struct mm_struct *mm, unsigned long addr, pmd_t pmd)
 {
 	return pmd_leaf(pmd) && (pmd_val(pmd) & _PAGE_PRESENT) && (pmd_val(pmd) & _PAGE_USER);
 }
 
-static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr)
+static inline bool pud_user_accessible_page(struct mm_struct *mm, unsigned long addr, pud_t pud)
 {
 	return pud_leaf(pud) && (pud_val(pud) & _PAGE_PRESENT) && (pud_val(pud) & _PAGE_USER);
 }
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index e87da25..62936a3 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -2448,12 +2448,6 @@ void __init alternative_instructions(void)
 					    __smp_locks, __smp_locks_end,
 					    _text, _etext);
 	}
-
-	if (!uniproc_patched || num_possible_cpus() == 1) {
-		free_init_pages("SMP alternatives",
-				(unsigned long)__smp_locks,
-				(unsigned long)__smp_locks_end);
-	}
 #endif
 
 	restart_nmi();
@@ -2462,6 +2456,24 @@ void __init alternative_instructions(void)
 	alt_reloc_selftest();
 }
 
+#ifdef CONFIG_SMP
+/*
+ * With CONFIG_DEFERRED_STRUCT_PAGE_INIT enabled we can free_init_pages() only
+ * after the deferred initialization of the memory map is complete.
+ */
+static int __init free_smp_locks(void)
+{
+	if (!uniproc_patched || num_possible_cpus() == 1) {
+		free_init_pages("SMP alternatives",
+				(unsigned long)__smp_locks,
+				(unsigned long)__smp_locks_end);
+	}
+
+	return 0;
+}
+arch_initcall(free_smp_locks);
+#endif
+
 /**
  * text_poke_early - Update instructions on a live kernel at boot time
  * @addr: address to modify
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index a7dfc29..b5b6a58 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -237,8 +237,12 @@ void hv_remove_crash_handler(void)
 #ifdef CONFIG_KEXEC_CORE
 static void hv_machine_shutdown(void)
 {
-	if (kexec_in_progress && hv_kexec_handler)
-		hv_kexec_handler();
+	if (kexec_in_progress) {
+		hv_stimer_global_cleanup();
+
+		if (hv_kexec_handler)
+			hv_kexec_handler();
+	}
 
 	/*
 	 * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
@@ -427,6 +431,10 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
 	}
 
 #ifdef CONFIG_X86_64
+	/* If AP LPs exist, we are in a kexec'd kernel and VPs already exist */
+	if (num_present_cpus() == 1 || hv_lp_exists(1))
+		return;
+
 	for_each_present_cpu(i) {
 		if (i == 0)
 			continue;
@@ -434,6 +442,9 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
 		BUG_ON(ret);
 	}
 
+	ret = hv_call_notify_all_processors_started();
+	WARN_ON(ret);
+
 	for_each_present_cpu(i) {
 		if (i == 0)
 			continue;
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 8b1a973..96af124 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -407,10 +407,11 @@ static void kgdb_disable_hw_debug(struct pt_regs *regs)
  *	kgdb_roundup_cpus - Get other CPUs into a holding pattern
  *
  *	On SMP systems, we need to get the attention of the other CPUs
- *	and get them be in a known state.  This should do what is needed
- *	to get the other CPUs to call kgdb_wait(). Note that on some arches,
- *	the NMI approach is not used for rounding up all the CPUs. For example,
- *	in case of MIPS, smp_call_function() is used to roundup CPUs.
+ *	and get them into a known state.  This should do what is needed
+ *	to get the other CPUs to call kgdb_handle_exception().  Note that
+ *	on some arches, the NMI approach is not used for rounding up all
+ *	the CPUs.  For example, in case of MIPS, smp_call_function() is
+ *	used to roundup CPUs.
  *
  *	On non-SMP systems, this is not called.
  */
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c
index 79bc8a9..44d4b2c 100644
--- a/arch/x86/kernel/resource.c
+++ b/arch/x86/kernel/resource.c
@@ -62,7 +62,7 @@ void arch_remove_reservations(struct resource *avail)
 	/*
 	 * Trim out BIOS area (high 2MB) and E820 regions. We do not remove
 	 * the low 1MB unconditionally, as this area is needed for some ISA
-	 * cards requiring a memory range, e.g. the i82365 PCMCIA controller.
+	 * cards requiring a memory range.
 	 */
 	if (avail->flags & IORESOURCE_MEM) {
 		resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index eebcc9d..46882ce 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -426,7 +426,7 @@ int __init ima_free_kexec_buffer(void)
 	if (!ima_kexec_buffer_size)
 		return -ENOENT;
 
-	memblock_free_late(ima_kexec_buffer_phys,
+	memblock_phys_free(ima_kexec_buffer_phys,
 			   ima_kexec_buffer_size);
 
 	ima_kexec_buffer_phys = 0;
diff --git a/arch/x86/kernel/shstk.c b/arch/x86/kernel/shstk.c
index 0962ae4..0ca649001 100644
--- a/arch/x86/kernel/shstk.c
+++ b/arch/x86/kernel/shstk.c
@@ -326,10 +326,8 @@ static int shstk_push_sigframe(unsigned long *ssp)
 
 static int shstk_pop_sigframe(unsigned long *ssp)
 {
-	struct vm_area_struct *vma;
 	unsigned long token_addr;
-	bool need_to_check_vma;
-	int err = 1;
+	unsigned int seq;
 
 	/*
 	 * It is possible for the SSP to be off the end of a shadow stack by 4
@@ -340,25 +338,35 @@ static int shstk_pop_sigframe(unsigned long *ssp)
 	if (!IS_ALIGNED(*ssp, 8))
 		return -EINVAL;
 
-	need_to_check_vma = PAGE_ALIGN(*ssp) == *ssp;
+	do {
+		struct vm_area_struct *vma;
+		bool valid_vma;
+		int err;
 
-	if (need_to_check_vma)
 		if (mmap_read_lock_killable(current->mm))
 			return -EINTR;
 
-	err = get_shstk_data(&token_addr, (unsigned long __user *)*ssp);
-	if (unlikely(err))
-		goto out_err;
-
-	if (need_to_check_vma) {
 		vma = find_vma(current->mm, *ssp);
-		if (!vma || !(vma->vm_flags & VM_SHADOW_STACK)) {
-			err = -EFAULT;
-			goto out_err;
-		}
+		valid_vma = vma && (vma->vm_flags & VM_SHADOW_STACK);
 
+		/*
+		 * VMAs can change between get_shstk_data() and find_vma().
+		 * Watch for changes and ensure that 'token_addr' comes from
+		 * 'vma' by recording a seqcount.
+		 *
+		 * Ignore the return value of mmap_lock_speculate_try_begin()
+		 * because the mmap lock excludes the possibility of writers.
+		 */
+		mmap_lock_speculate_try_begin(current->mm, &seq);
 		mmap_read_unlock(current->mm);
-	}
+
+		if (!valid_vma)
+			return -EINVAL;
+
+		err = get_shstk_data(&token_addr, (unsigned long __user *)*ssp);
+		if (err)
+			return err;
+	} while (mmap_lock_speculate_retry(current->mm, seq));
 
 	/* Restore SSP aligned? */
 	if (unlikely(!IS_ALIGNED(token_addr, 8)))
@@ -371,10 +379,6 @@ static int shstk_pop_sigframe(unsigned long *ssp)
 	*ssp = token_addr;
 
 	return 0;
-out_err:
-	if (need_to_check_vma)
-		mmap_read_unlock(current->mm);
-	return err;
 }
 
 int setup_signal_shadow_stack(struct ksignal *ksig)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index cba907c..d023a40 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -399,6 +399,15 @@ static void cpa_flush_all(unsigned long cache)
 	on_each_cpu(__cpa_flush_all, (void *) cache, 1);
 }
 
+static void __cpa_flush_tlb(void *data)
+{
+	struct cpa_data *cpa = data;
+	unsigned int i;
+
+	for (i = 0; i < cpa->numpages; i++)
+		flush_tlb_one_kernel(fix_addr(__cpa_addr(cpa, i)));
+}
+
 static int collapse_large_pages(unsigned long addr, struct list_head *pgtables);
 
 static void cpa_collapse_large_pages(struct cpa_data *cpa)
@@ -435,7 +444,6 @@ static void cpa_collapse_large_pages(struct cpa_data *cpa)
 
 static void cpa_flush(struct cpa_data *cpa, int cache)
 {
-	unsigned long start, end;
 	unsigned int i;
 
 	BUG_ON(irqs_disabled() && !early_boot_irqs_disabled);
@@ -445,12 +453,10 @@ static void cpa_flush(struct cpa_data *cpa, int cache)
 		goto collapse_large_pages;
 	}
 
-	start = fix_addr(__cpa_addr(cpa, 0));
-	end =   start + cpa->numpages * PAGE_SIZE;
-	if (cpa->force_flush_all)
-		end = TLB_FLUSH_ALL;
-
-	flush_tlb_kernel_range(start, end);
+	if (cpa->force_flush_all || cpa->numpages > tlb_single_page_flush_ceiling)
+		flush_tlb_all();
+	else
+		on_each_cpu(__cpa_flush_tlb, cpa, 1);
 
 	if (!cache)
 		goto collapse_large_pages;
diff --git a/arch/x86/mm/pti.c b/arch/x86/mm/pti.c
index f7546e9..631f037 100644
--- a/arch/x86/mm/pti.c
+++ b/arch/x86/mm/pti.c
@@ -105,6 +105,11 @@ void __init pti_check_boottime_disable(void)
 		pr_debug("PTI enabled, disabling INVLPGB\n");
 		setup_clear_cpu_cap(X86_FEATURE_INVLPGB);
 	}
+
+	if (cpu_feature_enabled(X86_FEATURE_FRED)) {
+		pr_debug("PTI enabled, disabling FRED\n");
+		setup_clear_cpu_cap(X86_FEATURE_FRED);
+	}
 }
 
 static int __init pti_parse_cmdline(char *arg)
diff --git a/arch/x86/platform/efi/memmap.c b/arch/x86/platform/efi/memmap.c
index 023697c..697a9a2 100644
--- a/arch/x86/platform/efi/memmap.c
+++ b/arch/x86/platform/efi/memmap.c
@@ -34,10 +34,7 @@ static
 void __init __efi_memmap_free(u64 phys, unsigned long size, unsigned long flags)
 {
 	if (flags & EFI_MEMMAP_MEMBLOCK) {
-		if (slab_is_available())
-			memblock_free_late(phys, size);
-		else
-			memblock_phys_free(phys, size);
+		memblock_phys_free(phys, size);
 	} else if (flags & EFI_MEMMAP_SLAB) {
 		struct page *p = pfn_to_page(PHYS_PFN(phys));
 		unsigned int order = get_order(size);
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 79f0818..df24ffc 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -372,7 +372,7 @@ void __init efi_reserve_boot_services(void)
 		 * doesn't make sense as far as the firmware is
 		 * concerned, but it does provide us with a way to tag
 		 * those regions that must not be paired with
-		 * memblock_free_late().
+		 * memblock_phys_free().
 		 */
 		md->attribute |= EFI_MEMORY_RUNTIME;
 	}
diff --git a/arch/x86/um/os-Linux/mcontext.c b/arch/x86/um/os-Linux/mcontext.c
index a21403df..b1580df 100644
--- a/arch/x86/um/os-Linux/mcontext.c
+++ b/arch/x86/um/os-Linux/mcontext.c
@@ -4,7 +4,13 @@
 #include <linux/string.h>
 #include <sys/ucontext.h>
 #include <asm/ptrace.h>
+/*
+ * musl defines struct sigcontext in <bits/signal.h>.  Rename the kernel's
+ * copy to avoid redefinition while keeping the FP-state types available.
+ */
+#define sigcontext __kernel_sigcontext
 #include <asm/sigcontext.h>
+#undef sigcontext
 #include <sysdep/ptrace.h>
 #include <sysdep/mcontext.h>
 #include <arch.h>
diff --git a/arch/x86/um/vdso/Makefile b/arch/x86/um/vdso/Makefile
index 8a7c8b3..7664cbe 100644
--- a/arch/x86/um/vdso/Makefile
+++ b/arch/x86/um/vdso/Makefile
@@ -3,8 +3,6 @@
 # Building vDSO images for x86.
 #
 
-vdso-install-y += vdso.so
-
 # files to link into the vdso
 vobjs-y := vdso-note.o um_vdso.o
 
diff --git a/arch/xtensa/include/asm/ucontext.h b/arch/xtensa/include/asm/ucontext.h
deleted file mode 100644
index 94c94ed..0000000
--- a/arch/xtensa/include/asm/ucontext.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * include/asm-xtensa/ucontext.h
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_UCONTEXT_H
-#define _XTENSA_UCONTEXT_H
-
-struct ucontext {
-	unsigned long	  uc_flags;
-	struct ucontext  *uc_link;
-	stack_t		  uc_stack;
-	struct sigcontext uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif /* _XTENSA_UCONTEXT_H */
diff --git a/arch/xtensa/include/uapi/asm/Kbuild b/arch/xtensa/include/uapi/asm/Kbuild
index b97c552..da95c5a 100644
--- a/arch/xtensa/include/uapi/asm/Kbuild
+++ b/arch/xtensa/include/uapi/asm/Kbuild
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 generated-y += unistd_32.h
+generic-y += ucontext.h
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index 0f1fe13..21283ac 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -32,8 +32,7 @@ static int iss_power_off(struct sys_off_data *unused)
 	return NOTIFY_DONE;
 }
 
-static int iss_restart(struct notifier_block *this,
-		       unsigned long event, void *ptr)
+static int iss_restart(struct sys_off_data *unused)
 {
 	/* Flush and reset the mmu, simulate a processor reset, and
 	 * jump to the reset vector. */
@@ -42,10 +41,6 @@ static int iss_restart(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block iss_restart_block = {
-	.notifier_call = iss_restart,
-};
-
 static int
 iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
@@ -84,7 +79,9 @@ void __init platform_setup(char **p_cmdline)
 	}
 
 	atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
-	register_restart_handler(&iss_restart_block);
+	register_sys_off_handler(SYS_OFF_MODE_RESTART,
+				 SYS_OFF_PRIO_PLATFORM,
+				 iss_restart, NULL);
 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
 				 SYS_OFF_PRIO_PLATFORM,
 				 iss_power_off, NULL);
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c
index 258e01a..eda4c15 100644
--- a/arch/xtensa/platforms/xt2000/setup.c
+++ b/arch/xtensa/platforms/xt2000/setup.c
@@ -50,8 +50,7 @@ static int xt2000_power_off(struct sys_off_data *unused)
 	return NOTIFY_DONE;
 }
 
-static int xt2000_restart(struct notifier_block *this,
-			  unsigned long event, void *ptr)
+static int xt2000_restart(struct sys_off_data *unused)
 {
 	/* Flush and reset the mmu, simulate a processor reset, and
 	 * jump to the reset vector. */
@@ -60,10 +59,6 @@ static int xt2000_restart(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block xt2000_restart_block = {
-	.notifier_call = xt2000_restart,
-};
-
 void __init platform_setup(char** cmdline)
 {
 	led_print (0, "LINUX   ");
@@ -140,7 +135,9 @@ static int __init xt2000_setup_devinit(void)
 	platform_device_register(&xt2000_serial8250_device);
 	platform_device_register(&xt2000_sonic_device);
 	mod_timer(&heartbeat_timer, jiffies + HZ / 2);
-	register_restart_handler(&xt2000_restart_block);
+	register_sys_off_handler(SYS_OFF_MODE_RESTART,
+				 SYS_OFF_PRIO_PLATFORM,
+				 xt2000_restart, NULL);
 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
 				 SYS_OFF_PRIO_DEFAULT,
 				 xt2000_power_off, NULL);
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
index a2432f0..67d7f37 100644
--- a/arch/xtensa/platforms/xtfpga/setup.c
+++ b/arch/xtensa/platforms/xtfpga/setup.c
@@ -42,8 +42,7 @@ static int xtfpga_power_off(struct sys_off_data *unused)
 	return NOTIFY_DONE;
 }
 
-static int xtfpga_restart(struct notifier_block *this,
-			  unsigned long event, void *ptr)
+static int xtfpga_restart(struct sys_off_data *unused)
 {
 	/* Try software reset first. */
 	WRITE_ONCE(*(u32 *)XTFPGA_SWRST_VADDR, 0xdead);
@@ -56,10 +55,6 @@ static int xtfpga_restart(struct notifier_block *this,
 	return NOTIFY_DONE;
 }
 
-static struct notifier_block xtfpga_restart_block = {
-	.notifier_call = xtfpga_restart,
-};
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 
 void __init platform_calibrate_ccount(void)
@@ -71,7 +66,9 @@ void __init platform_calibrate_ccount(void)
 
 static void __init xtfpga_register_handlers(void)
 {
-	register_restart_handler(&xtfpga_restart_block);
+	register_sys_off_handler(SYS_OFF_MODE_RESTART,
+				 SYS_OFF_PRIO_PLATFORM,
+				 xtfpga_restart, NULL);
 	register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
 				 SYS_OFF_PRIO_DEFAULT,
 				 xtfpga_power_off, NULL);
diff --git a/certs/extract-cert.c b/certs/extract-cert.c
index 8c762f9..f3eb2c4 100644
--- a/certs/extract-cert.c
+++ b/certs/extract-cert.c
@@ -41,7 +41,9 @@ void format(void)
 	exit(2);
 }
 
+#ifdef USE_PKCS11_ENGINE
 static const char *key_pass;
+#endif
 static BIO *wb;
 static char *cert_dst;
 static bool verbose;
@@ -133,7 +135,9 @@ int main(int argc, char **argv)
 	if (verbose_env && strchr(verbose_env, '1'))
 		verbose = true;
 
-        key_pass = getenv("KBUILD_SIGN_PIN");
+#ifdef USE_PKCS11_ENGINE
+	key_pass = getenv("KBUILD_SIGN_PIN");
+#endif
 
 	if (argc != 3)
 		format();
diff --git a/crypto/acompress.c b/crypto/acompress.c
index 1f9cb04..6025c1a 100644
--- a/crypto/acompress.c
+++ b/crypto/acompress.c
@@ -169,15 +169,13 @@ static void acomp_save_req(struct acomp_req *req, crypto_completion_t cplt)
 	state->compl = req->base.complete;
 	state->data = req->base.data;
 	req->base.complete = cplt;
-	req->base.data = state;
+	req->base.data = req;
 }
 
 static void acomp_restore_req(struct acomp_req *req)
 {
-	struct acomp_req_chain *state = req->base.data;
-
-	req->base.complete = state->compl;
-	req->base.data = state->data;
+	req->base.complete = req->chain.compl;
+	req->base.data = req->chain.data;
 }
 
 static void acomp_reqchain_virt(struct acomp_req *req)
diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c
index f8bd45f..cb651ab 100644
--- a/crypto/algif_aead.c
+++ b/crypto/algif_aead.c
@@ -72,8 +72,10 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
 	struct af_alg_ctx *ctx = ask->private;
 	struct crypto_aead *tfm = pask->private;
 	unsigned int as = crypto_aead_authsize(tfm);
+	unsigned int ivsize = crypto_aead_ivsize(tfm);
 	struct af_alg_async_req *areq;
 	struct scatterlist *rsgl_src, *tsgl_src = NULL;
+	void *iv;
 	int err = 0;
 	size_t used = 0;		/* [in]  TX bufs to be en/decrypted */
 	size_t outlen = 0;		/* [out] RX bufs produced by kernel */
@@ -125,10 +127,14 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
 
 	/* Allocate cipher request for current operation. */
 	areq = af_alg_alloc_areq(sk, sizeof(struct af_alg_async_req) +
-				     crypto_aead_reqsize(tfm));
+				     crypto_aead_reqsize(tfm) + ivsize);
 	if (IS_ERR(areq))
 		return PTR_ERR(areq);
 
+	iv = (u8 *)aead_request_ctx(&areq->cra_u.aead_req) +
+	     crypto_aead_reqsize(tfm);
+	memcpy(iv, ctx->iv, ivsize);
+
 	/* convert iovecs of output buffers into RX SGL */
 	err = af_alg_get_rsgl(sk, msg, flags, areq, outlen, &usedpages);
 	if (err)
@@ -187,7 +193,7 @@ static int _aead_recvmsg(struct socket *sock, struct msghdr *msg,
 
 	/* Initialize the crypto operation */
 	aead_request_set_crypt(&areq->cra_u.aead_req, tsgl_src,
-			       areq->first_rsgl.sgl.sgt.sgl, used, ctx->iv);
+			       areq->first_rsgl.sgl.sgt.sgl, used, iv);
 	aead_request_set_ad(&areq->cra_u.aead_req, ctx->aead_assoclen);
 	aead_request_set_tfm(&areq->cra_u.aead_req, tfm);
 
diff --git a/crypto/authencesn.c b/crypto/authencesn.c
index c0a01d7..af3d584 100644
--- a/crypto/authencesn.c
+++ b/crypto/authencesn.c
@@ -228,9 +228,11 @@ static int crypto_authenc_esn_decrypt_tail(struct aead_request *req,
 
 decrypt:
 
-	if (src != dst)
-		src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
 	dst = scatterwalk_ffwd(areq_ctx->dst, dst, assoclen);
+	if (req->src == req->dst)
+		src = dst;
+	else
+		src = scatterwalk_ffwd(areq_ctx->src, src, assoclen);
 
 	skcipher_request_set_tfm(skreq, ctx->enc);
 	skcipher_request_set_callback(skreq, flags,
diff --git a/crypto/krb5enc.c b/crypto/krb5enc.c
index 1bfe837..fefa8d2 100644
--- a/crypto/krb5enc.c
+++ b/crypto/krb5enc.c
@@ -39,12 +39,6 @@ struct krb5enc_request_ctx {
 	char tail[];
 };
 
-static void krb5enc_request_complete(struct aead_request *req, int err)
-{
-	if (err != -EINPROGRESS)
-		aead_request_complete(req, err);
-}
-
 /**
  * crypto_krb5enc_extractkeys - Extract Ke and Ki keys from the key blob.
  * @keys: Where to put the key sizes and pointers
@@ -127,7 +121,7 @@ static void krb5enc_encrypt_done(void *data, int err)
 {
 	struct aead_request *req = data;
 
-	krb5enc_request_complete(req, err);
+	aead_request_complete(req, err);
 }
 
 /*
@@ -188,14 +182,16 @@ static void krb5enc_encrypt_ahash_done(void *data, int err)
 	struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff);
 
 	if (err)
-		return krb5enc_request_complete(req, err);
+		goto out;
 
 	krb5enc_insert_checksum(req, ahreq->result);
 
-	err = krb5enc_dispatch_encrypt(req,
-				       aead_request_flags(req) & ~CRYPTO_TFM_REQ_MAY_SLEEP);
-	if (err != -EINPROGRESS)
-		aead_request_complete(req, err);
+	err = krb5enc_dispatch_encrypt(req, 0);
+	if (err == -EINPROGRESS)
+		return;
+
+out:
+	aead_request_complete(req, err);
 }
 
 /*
@@ -265,17 +261,16 @@ static void krb5enc_decrypt_hash_done(void *data, int err)
 {
 	struct aead_request *req = data;
 
-	if (err)
-		return krb5enc_request_complete(req, err);
-
-	err = krb5enc_verify_hash(req);
-	krb5enc_request_complete(req, err);
+	if (!err)
+		err = krb5enc_verify_hash(req);
+	aead_request_complete(req, err);
 }
 
 /*
  * Dispatch the hashing of the plaintext after we've done the decryption.
  */
-static int krb5enc_dispatch_decrypt_hash(struct aead_request *req)
+static int krb5enc_dispatch_decrypt_hash(struct aead_request *req,
+					 unsigned int flags)
 {
 	struct crypto_aead *krb5enc = crypto_aead_reqtfm(req);
 	struct aead_instance *inst = aead_alg_instance(krb5enc);
@@ -291,7 +286,7 @@ static int krb5enc_dispatch_decrypt_hash(struct aead_request *req)
 	ahash_request_set_tfm(ahreq, auth);
 	ahash_request_set_crypt(ahreq, req->dst, hash,
 				req->assoclen + req->cryptlen - authsize);
-	ahash_request_set_callback(ahreq, aead_request_flags(req),
+	ahash_request_set_callback(ahreq, flags,
 				   krb5enc_decrypt_hash_done, req);
 
 	err = crypto_ahash_digest(ahreq);
@@ -301,6 +296,21 @@ static int krb5enc_dispatch_decrypt_hash(struct aead_request *req)
 	return krb5enc_verify_hash(req);
 }
 
+static void krb5enc_decrypt_done(void *data, int err)
+{
+	struct aead_request *req = data;
+
+	if (err)
+		goto out;
+
+	err = krb5enc_dispatch_decrypt_hash(req, 0);
+	if (err == -EINPROGRESS)
+		return;
+
+out:
+	aead_request_complete(req, err);
+}
+
 /*
  * Dispatch the decryption of the ciphertext.
  */
@@ -324,7 +334,7 @@ static int krb5enc_dispatch_decrypt(struct aead_request *req)
 
 	skcipher_request_set_tfm(skreq, ctx->enc);
 	skcipher_request_set_callback(skreq, aead_request_flags(req),
-				      req->base.complete, req->base.data);
+				      krb5enc_decrypt_done, req);
 	skcipher_request_set_crypt(skreq, src, dst,
 				   req->cryptlen - authsize, req->iv);
 
@@ -339,7 +349,7 @@ static int krb5enc_decrypt(struct aead_request *req)
 	if (err < 0)
 		return err;
 
-	return krb5enc_dispatch_decrypt_hash(req);
+	return krb5enc_dispatch_decrypt_hash(req, aead_request_flags(req));
 }
 
 static int krb5enc_init_tfm(struct crypto_aead *tfm)
diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c
index c3a9d4f..ed0feab 100644
--- a/crypto/pcrypt.c
+++ b/crypto/pcrypt.c
@@ -69,6 +69,9 @@ static void pcrypt_aead_done(void *data, int err)
 	struct pcrypt_request *preq = aead_request_ctx(req);
 	struct padata_priv *padata = pcrypt_request_padata(preq);
 
+	if (err == -EINPROGRESS)
+		return;
+
 	padata->info = err;
 
 	padata_do_serial(padata);
@@ -82,7 +85,7 @@ static void pcrypt_aead_enc(struct padata_priv *padata)
 
 	ret = crypto_aead_encrypt(req);
 
-	if (ret == -EINPROGRESS)
+	if (ret == -EINPROGRESS || ret == -EBUSY)
 		return;
 
 	padata->info = ret;
@@ -133,7 +136,7 @@ static void pcrypt_aead_dec(struct padata_priv *padata)
 
 	ret = crypto_aead_decrypt(req);
 
-	if (ret == -EINPROGRESS)
+	if (ret == -EINPROGRESS || ret == -EBUSY)
 		return;
 
 	padata->info = ret;
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c0f1fb8..f2bed2d 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -61,8 +61,6 @@
 
 source "drivers/net/Kconfig"
 
-source "drivers/isdn/Kconfig"
-
 # input before char - char/joystick depends on it. As does USB.
 
 source "drivers/input/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 53fbd2e0..0841ea8 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -124,7 +124,6 @@
 obj-$(CONFIG_MD)		+= md/
 obj-$(CONFIG_BT)		+= bluetooth/
 obj-$(CONFIG_ACCESSIBILITY)	+= accessibility/
-obj-$(CONFIG_ISDN)		+= isdn/
 obj-$(CONFIG_EDAC)		+= edac/
 obj-$(CONFIG_EISA)		+= eisa/
 obj-$(CONFIG_PM_OPP)		+= opp/
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 6b1680e..d4131c1 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -987,7 +987,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle)
 	return device;
 
  err:
-	acpi_release_power_resource(&device->dev);
+	acpi_dev_put(device);
 	return NULL;
 }
 
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e8cdbdb..530547c 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1900,7 +1900,7 @@ static int acpi_add_single_object(struct acpi_device **child,
 		result = acpi_device_add(device);
 
 	if (result) {
-		acpi_device_release(&device->dev);
+		acpi_dev_put(device);
 		return result;
 	}
 
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 4cf74f1..0a3c823 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -878,6 +878,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
 		DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7760 AIO"),
 		},
 	},
+	{
+	 .callback = video_detect_force_native,
+	 /* Dell OptiPlex 7770 AIO */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+		DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7770 AIO"),
+		},
+	},
 
 	/*
 	 * Models which have nvidia-ec-wmi support, but should not use it.
@@ -899,6 +907,15 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
 		DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15 3535"),
 		},
 	},
+	{
+	 /* https://gitlab.freedesktop.org/drm/amd/-/issues/4512 */
+	 .callback = video_detect_force_native,
+	 /* Lenovo Legion S7 15ACH6 */
+	 .matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "82K8"),
+		},
+	},
 
 	/*
 	 * x86 android tablets which directly control the backlight through
@@ -948,14 +965,6 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
 		DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
 		},
 	},
-	/* https://gitlab.freedesktop.org/drm/amd/-/issues/4512 */
-	{
-	 .callback = video_detect_force_native,
-	 .matches = {
-		DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-		DMI_MATCH(DMI_PRODUCT_NAME, "82K8"),
-		},
-	},
 	{ },
 };
 
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 21f91d9f..9e61942 100644
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -3117,7 +3117,7 @@ static void binder_transaction(struct binder_proc *proc,
 	t->start_time = t_start_time;
 	t->from_pid = proc->pid;
 	t->from_tid = thread->pid;
-	t->sender_euid = task_euid(proc->tsk);
+	t->sender_euid = current_euid();
 	t->code = tr->code;
 	t->flags = tr->flags;
 	t->priority = task_nice(current);
diff --git a/drivers/android/binder/allocation.rs b/drivers/android/binder/allocation.rs
index 7f65a9c..0cab959 100644
--- a/drivers/android/binder/allocation.rs
+++ b/drivers/android/binder/allocation.rs
@@ -56,7 +56,6 @@ pub(crate) struct Allocation {
     pub(crate) process: Arc<Process>,
     allocation_info: Option<AllocationInfo>,
     free_on_drop: bool,
-    pub(crate) oneway_spam_detected: bool,
     #[allow(dead_code)]
     pub(crate) debug_id: usize,
 }
@@ -68,7 +67,6 @@ pub(crate) fn new(
         offset: usize,
         size: usize,
         ptr: usize,
-        oneway_spam_detected: bool,
     ) -> Self {
         Self {
             process,
@@ -76,7 +74,6 @@ pub(crate) fn new(
             size,
             ptr,
             debug_id,
-            oneway_spam_detected,
             allocation_info: None,
             free_on_drop: true,
         }
@@ -208,6 +205,7 @@ pub(crate) fn translate_fds(&mut self) -> Result<TranslatedFds> {
             let res = FileDescriptorReservation::get_unused_fd_flags(bindings::O_CLOEXEC)?;
             let fd = res.reserved_fd();
             self.write::<u32>(file_info.buffer_offset, &fd)?;
+            crate::trace::trace_transaction_fd_recv(self.debug_id, fd, file_info.buffer_offset);
 
             reservations.push(
                 Reservation {
@@ -260,19 +258,22 @@ fn drop(&mut self) {
                 }
             }
 
-            for &fd in &info.file_list.close_on_free {
-                let closer = match DeferredFdCloser::new(GFP_KERNEL) {
-                    Ok(closer) => closer,
-                    Err(kernel::alloc::AllocError) => {
-                        // Ignore allocation failures.
-                        break;
-                    }
-                };
+            if self.process.task == kernel::current!().group_leader() {
+                for &fd in &info.file_list.close_on_free {
+                    let closer = match DeferredFdCloser::new(GFP_KERNEL) {
+                        Ok(closer) => closer,
+                        Err(kernel::alloc::AllocError) => {
+                            // Ignore allocation failures.
+                            break;
+                        }
+                    };
 
-                // Here, we ignore errors. The operation can fail if the fd is not valid, or if the
-                // method is called from a kthread. However, this is always called from a syscall,
-                // so the latter case cannot happen, and we don't care about the first case.
-                let _ = closer.close_fd(fd);
+                    // Here, we ignore errors. The operation can fail if the fd is not valid, or if
+                    // the method is called from a kthread. However, this is always called from a
+                    // syscall, so the latter case cannot happen, and we don't care about the first
+                    // case.
+                    let _ = closer.close_fd(fd);
+                }
             }
 
             if info.clear_on_free {
diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/context.rs
index 9cf437c..ddddb66 100644
--- a/drivers/android/binder/context.rs
+++ b/drivers/android/binder/context.rs
@@ -94,6 +94,17 @@ pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Arc<Process>) {
         }
         let mut manager = self.manager.lock();
         manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc));
+
+        // Shrink the vector if it has significant unused capacity to avoid memory waste,
+        // but use a conservative strategy to prevent shrink-then-regrow oscillation.
+        // Only shrink when length drops below 1/4 of capacity, and shrink to twice the length.
+        let len = manager.all_procs.len();
+        let cap = manager.all_procs.capacity();
+        if len < cap / 4 {
+            // Shrink to twice the current length. Ignore allocation failures since this
+            // is just an optimization; the vector remains valid even if shrinking fails.
+            let _ = manager.all_procs.shrink_to(len * 2, GFP_KERNEL);
+        }
     }
 
     pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result {
diff --git a/drivers/android/binder/error.rs b/drivers/android/binder/error.rs
index b24497c..45d85d4 100644
--- a/drivers/android/binder/error.rs
+++ b/drivers/android/binder/error.rs
@@ -13,7 +13,7 @@
 /// errno.
 pub(crate) struct BinderError {
     pub(crate) reply: u32,
-    source: Option<Error>,
+    pub(crate) source: Option<Error>,
 }
 
 impl BinderError {
@@ -41,14 +41,6 @@ pub(crate) fn new_frozen_oneway() -> Self {
     pub(crate) fn is_dead(&self) -> bool {
         self.reply == BR_DEAD_REPLY
     }
-
-    pub(crate) fn as_errno(&self) -> kernel::ffi::c_int {
-        self.source.unwrap_or(EINVAL).to_errno()
-    }
-
-    pub(crate) fn should_pr_warn(&self) -> bool {
-        self.source.is_some()
-    }
 }
 
 /// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index f064981..820cbd5 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -48,6 +48,7 @@
     range_alloc::{RangeAllocator, ReserveNew, ReserveNewArgs},
     stats::BinderStats,
     thread::{PushWorkRes, Thread},
+    transaction::TransactionInfo,
     BinderfsProcFile, DArc, DLArc, DTRWrap, DeliverToRead,
 };
 
@@ -681,7 +682,7 @@ pub(crate) fn get_work_or_register<'a>(
     fn get_current_thread(self: ArcBorrow<'_, Self>) -> Result<Arc<Thread>> {
         let id = {
             let current = kernel::current!();
-            if !core::ptr::eq(current.group_leader(), &*self.task) {
+            if self.task != current.group_leader() {
                 pr_err!("get_current_thread was called from the wrong process.");
                 return Err(EINVAL);
             }
@@ -1003,16 +1004,15 @@ pub(crate) fn buffer_alloc(
         self: &Arc<Self>,
         debug_id: usize,
         size: usize,
-        is_oneway: bool,
-        from_pid: i32,
+        info: &mut TransactionInfo,
     ) -> BinderResult<NewAllocation> {
         use kernel::page::PAGE_SIZE;
 
         let mut reserve_new_args = ReserveNewArgs {
             debug_id,
             size,
-            is_oneway,
-            pid: from_pid,
+            is_oneway: info.is_oneway(),
+            pid: info.from_pid,
             ..ReserveNewArgs::default()
         };
 
@@ -1028,13 +1028,13 @@ pub(crate) fn buffer_alloc(
             reserve_new_args = alloc_request.make_alloc()?;
         };
 
+        info.oneway_spam_suspect = new_alloc.oneway_spam_detected;
         let res = Allocation::new(
             self.clone(),
             debug_id,
             new_alloc.offset,
             size,
             addr + new_alloc.offset,
-            new_alloc.oneway_spam_detected,
         );
 
         // This allocation will be marked as in use until the `Allocation` is used to free it.
@@ -1066,7 +1066,7 @@ pub(crate) fn buffer_get(self: &Arc<Self>, ptr: usize) -> Option<Allocation> {
         let mapping = inner.mapping.as_mut()?;
         let offset = ptr.checked_sub(mapping.address)?;
         let (size, debug_id, odata) = mapping.alloc.reserve_existing(offset).ok()?;
-        let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
+        let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr);
         if let Some(data) = odata {
             alloc.set_info(data);
         }
@@ -1414,8 +1414,7 @@ fn deferred_release(self: Arc<Self>) {
                 .alloc
                 .take_for_each(|offset, size, debug_id, odata| {
                     let ptr = offset + address;
-                    let mut alloc =
-                        Allocation::new(self.clone(), debug_id, offset, size, ptr, false);
+                    let mut alloc = Allocation::new(self.clone(), debug_id, offset, size, ptr);
                     if let Some(data) = odata {
                         alloc.set_info(data);
                     }
@@ -1443,6 +1442,9 @@ pub(crate) fn drop_outstanding_txn(&self) {
         }
     }
 
+    // #[export_name] is a temporary workaround so that ps output does not become unreadable from
+    // mangled symbol names.
+    #[export_name = "rust_binder_freeze"]
     pub(crate) fn ioctl_freeze(&self, info: &BinderFreezeInfo) -> Result {
         if info.enable == 0 {
             let msgs = self.prepare_freeze_messages()?;
@@ -1657,11 +1659,14 @@ pub(crate) fn ioctl(this: ArcBorrow<'_, Process>, file: &File, cmd: u32, arg: us
 
         const _IOC_READ_WRITE: u32 = _IOC_READ | _IOC_WRITE;
 
-        match _IOC_DIR(cmd) {
+        let res = match _IOC_DIR(cmd) {
             _IOC_WRITE => Self::ioctl_write_only(this, file, cmd, &mut user_slice.reader()),
             _IOC_READ_WRITE => Self::ioctl_write_read(this, file, cmd, user_slice),
             _ => Err(EINVAL),
-        }
+        };
+
+        crate::trace::trace_ioctl_done(res);
+        res
     }
 
     pub(crate) fn mmap(
@@ -1670,7 +1675,7 @@ pub(crate) fn mmap(
         vma: &mm::virt::VmaNew,
     ) -> Result {
         // We don't allow mmap to be used in a different process.
-        if !core::ptr::eq(kernel::current!().group_leader(), &*this.task) {
+        if this.task != kernel::current!().group_leader() {
             return Err(EINVAL);
         }
         if vma.start() == 0 {
diff --git a/drivers/android/binder/rust_binder.h b/drivers/android/binder/rust_binder.h
index d228472..3936b9d 100644
--- a/drivers/android/binder/rust_binder.h
+++ b/drivers/android/binder/rust_binder.h
@@ -99,4 +99,9 @@ static inline size_t rust_binder_node_debug_id(rust_binder_node t)
 	return *(size_t *) (t + RUST_BINDER_LAYOUT.n.debug_id);
 }
 
+static inline binder_uintptr_t rust_binder_node_ptr(rust_binder_node t)
+{
+	return *(binder_uintptr_t *) (t + RUST_BINDER_LAYOUT.n.ptr);
+}
+
 #endif
diff --git a/drivers/android/binder/rust_binder_events.h b/drivers/android/binder/rust_binder_events.h
index 8ad785c..1a44678 100644
--- a/drivers/android/binder/rust_binder_events.h
+++ b/drivers/android/binder/rust_binder_events.h
@@ -15,7 +15,7 @@
 
 #include <linux/tracepoint.h>
 
-TRACE_EVENT(rust_binder_ioctl,
+TRACE_EVENT(binder_ioctl,
 	TP_PROTO(unsigned int cmd, unsigned long arg),
 	TP_ARGS(cmd, arg),
 
@@ -30,7 +30,46 @@ TRACE_EVENT(rust_binder_ioctl,
 	TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg)
 );
 
-TRACE_EVENT(rust_binder_transaction,
+DECLARE_EVENT_CLASS(binder_function_return_class,
+	TP_PROTO(int ret),
+	TP_ARGS(ret),
+	TP_STRUCT__entry(
+		__field(int, ret)
+	),
+	TP_fast_assign(
+		__entry->ret = ret;
+	),
+	TP_printk("ret=%d", __entry->ret)
+);
+
+#define DEFINE_RBINDER_FUNCTION_RETURN_EVENT(name)	\
+DEFINE_EVENT(binder_function_return_class, name,	\
+	TP_PROTO(int ret), \
+	TP_ARGS(ret))
+
+DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_ioctl_done);
+DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_read_done);
+DEFINE_RBINDER_FUNCTION_RETURN_EVENT(binder_write_done);
+
+TRACE_EVENT(binder_wait_for_work,
+	TP_PROTO(bool proc_work, bool transaction_stack, bool thread_todo),
+	TP_ARGS(proc_work, transaction_stack, thread_todo),
+	TP_STRUCT__entry(
+		__field(bool, proc_work)
+		__field(bool, transaction_stack)
+		__field(bool, thread_todo)
+	),
+	TP_fast_assign(
+		__entry->proc_work = proc_work;
+		__entry->transaction_stack = transaction_stack;
+		__entry->thread_todo = thread_todo;
+	),
+	TP_printk("proc_work=%d transaction_stack=%d thread_todo=%d",
+		  __entry->proc_work, __entry->transaction_stack,
+		  __entry->thread_todo)
+);
+
+TRACE_EVENT(binder_transaction,
 	TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread),
 	TP_ARGS(reply, t, thread),
 	TP_STRUCT__entry(
@@ -60,6 +99,84 @@ TRACE_EVENT(rust_binder_transaction,
 		  __entry->reply, __entry->flags, __entry->code)
 );
 
+TRACE_EVENT(binder_transaction_received,
+	TP_PROTO(rust_binder_transaction t),
+	TP_ARGS(t),
+	TP_STRUCT__entry(
+		__field(int, debug_id)
+	),
+	TP_fast_assign(
+		__entry->debug_id = rust_binder_transaction_debug_id(t);
+	),
+	TP_printk("transaction=%d", __entry->debug_id)
+);
+
+TRACE_EVENT(binder_transaction_fd_send,
+	TP_PROTO(int t_debug_id, int fd, size_t offset),
+	TP_ARGS(t_debug_id, fd, offset),
+	TP_STRUCT__entry(
+		__field(int, debug_id)
+		__field(int, fd)
+		__field(size_t, offset)
+	),
+	TP_fast_assign(
+		__entry->debug_id = t_debug_id;
+		__entry->fd = fd;
+		__entry->offset = offset;
+	),
+	TP_printk("transaction=%d src_fd=%d offset=%zu",
+		  __entry->debug_id, __entry->fd, __entry->offset)
+);
+
+TRACE_EVENT(binder_transaction_fd_recv,
+	TP_PROTO(int t_debug_id, int fd, size_t offset),
+	TP_ARGS(t_debug_id, fd, offset),
+	TP_STRUCT__entry(
+		__field(int, debug_id)
+		__field(int, fd)
+		__field(size_t, offset)
+	),
+	TP_fast_assign(
+		__entry->debug_id = t_debug_id;
+		__entry->fd = fd;
+		__entry->offset = offset;
+	),
+	TP_printk("transaction=%d dest_fd=%d offset=%zu",
+		  __entry->debug_id, __entry->fd, __entry->offset)
+);
+
+TRACE_EVENT(binder_command,
+	TP_PROTO(uint32_t cmd),
+	TP_ARGS(cmd),
+	TP_STRUCT__entry(
+		__field(uint32_t, cmd)
+	),
+	TP_fast_assign(
+		__entry->cmd = cmd;
+	),
+	TP_printk("cmd=0x%x %s",
+		  __entry->cmd,
+		  _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_command_strings) ?
+			  binder_command_strings[_IOC_NR(__entry->cmd)] :
+			  "unknown")
+);
+
+TRACE_EVENT(binder_return,
+	TP_PROTO(uint32_t cmd),
+	TP_ARGS(cmd),
+	TP_STRUCT__entry(
+		__field(uint32_t, cmd)
+	),
+	TP_fast_assign(
+		__entry->cmd = cmd;
+	),
+	TP_printk("cmd=0x%x %s",
+		  __entry->cmd,
+		  _IOC_NR(__entry->cmd) < ARRAY_SIZE(binder_return_strings) ?
+			  binder_return_strings[_IOC_NR(__entry->cmd)] :
+			  "unknown")
+);
+
 #endif /* _RUST_BINDER_TRACE_H */
 
 /* This part must be outside protection */
diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs
index 632b547..dc1941c 100644
--- a/drivers/android/binder/rust_binder_main.rs
+++ b/drivers/android/binder/rust_binder_main.rs
@@ -118,6 +118,7 @@ fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
     /// Write a return code back to user space.
     /// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
     fn write_code(&mut self, code: u32) -> Result {
+        crate::trace::trace_return(code);
         stats::GLOBAL_STATS.inc_br(code);
         self.thread.process.stats.inc_br(code);
         self.writer.write(&code)
@@ -294,8 +295,6 @@ fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
         // SAFETY: The module initializer never runs twice, so we only call this once.
         unsafe { crate::context::CONTEXTS.init() };
 
-        pr_warn!("Loaded Rust Binder.");
-
         BINDER_SHRINKER.register(c"android-binder")?;
 
         // SAFETY: The module is being loaded, so we can initialize binderfs.
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index c004214..97d5f31 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -19,7 +19,7 @@
     sync::poll::{PollCondVar, PollTable},
     sync::{aref::ARef, Arc, SpinLock},
     task::Task,
-    uaccess::UserSlice,
+    uaccess::{UserPtr, UserSlice, UserSliceReader},
     uapi,
 };
 
@@ -30,7 +30,7 @@
     process::{GetWorkOrRegister, Process},
     ptr_align,
     stats::GLOBAL_STATS,
-    transaction::Transaction,
+    transaction::{Transaction, TransactionInfo},
     BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead,
 };
 
@@ -513,6 +513,9 @@ pub(crate) fn has_current_transaction(&self) -> bool {
     /// Attempts to fetch a work item from the thread-local queue. The behaviour if the queue is
     /// empty depends on `wait`: if it is true, the function waits for some work to be queued (or a
     /// signal); otherwise it returns indicating that none is available.
+    // #[export_name] is a temporary workaround so that ps output does not become unreadable from
+    // mangled symbol names.
+    #[export_name = "rust_binder_waitlcl"]
     fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> {
         {
             let mut inner = self.inner.lock();
@@ -551,6 +554,9 @@ fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn Deliv
     ///
     /// This must only be called when the thread is not participating in a transaction chain. If it
     /// is, the local version (`get_work_local`) should be used instead.
+    // #[export_name] is a temporary workaround so that ps output does not become unreadable from
+    // mangled symbol names.
+    #[export_name = "rust_binder_wait"]
     fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> {
         // Try to get work from the thread's work queue, using only a local lock.
         {
@@ -706,6 +712,7 @@ fn translate_object(
                     core::mem::offset_of!(uapi::binder_fd_object, __bindgen_anon_1.fd);
 
                 let field_offset = offset + FD_FIELD_OFFSET;
+                crate::trace::trace_transaction_fd_send(view.alloc.debug_id, fd, field_offset);
 
                 view.alloc.info_add_fd(file, field_offset, false)?;
             }
@@ -945,13 +952,11 @@ fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) ->
     pub(crate) fn copy_transaction_data(
         &self,
         to_process: Arc<Process>,
-        tr: &BinderTransactionDataSg,
+        info: &mut TransactionInfo,
         debug_id: usize,
         allow_fds: bool,
         txn_security_ctx_offset: Option<&mut usize>,
     ) -> BinderResult<NewAllocation> {
-        let trd = &tr.transaction_data;
-        let is_oneway = trd.flags & TF_ONE_WAY != 0;
         let mut secctx = if let Some(offset) = txn_security_ctx_offset {
             let secid = self.process.cred.get_secid();
             let ctx = match security::SecurityCtx::from_secid(secid) {
@@ -966,10 +971,10 @@ pub(crate) fn copy_transaction_data(
             None
         };
 
-        let data_size = trd.data_size.try_into().map_err(|_| EINVAL)?;
+        let data_size = info.data_size;
         let aligned_data_size = ptr_align(data_size).ok_or(EINVAL)?;
-        let offsets_size: usize = trd.offsets_size.try_into().map_err(|_| EINVAL)?;
-        let buffers_size: usize = tr.buffers_size.try_into().map_err(|_| EINVAL)?;
+        let offsets_size = info.offsets_size;
+        let buffers_size = info.buffers_size;
         let aligned_secctx_size = match secctx.as_ref() {
             Some((_offset, ctx)) => ptr_align(ctx.len()).ok_or(EINVAL)?,
             None => 0,
@@ -992,32 +997,25 @@ pub(crate) fn copy_transaction_data(
             size_of::<u64>(),
         );
         let secctx_off = aligned_data_size + offsets_size + buffers_size;
-        let mut alloc =
-            match to_process.buffer_alloc(debug_id, len, is_oneway, self.process.task.pid()) {
-                Ok(alloc) => alloc,
-                Err(err) => {
-                    pr_warn!(
-                        "Failed to allocate buffer. len:{}, is_oneway:{}",
-                        len,
-                        is_oneway
-                    );
-                    return Err(err);
-                }
-            };
+        let mut alloc = match to_process.buffer_alloc(debug_id, len, info) {
+            Ok(alloc) => alloc,
+            Err(err) => {
+                pr_warn!(
+                    "Failed to allocate buffer. len:{}, is_oneway:{}",
+                    len,
+                    info.is_oneway(),
+                );
+                return Err(err);
+            }
+        };
 
-        // SAFETY: This accesses a union field, but it's okay because the field's type is valid for
-        // all bit-patterns.
-        let trd_data_ptr = unsafe { &trd.data.ptr };
-        let mut buffer_reader =
-            UserSlice::new(UserPtr::from_addr(trd_data_ptr.buffer as _), data_size).reader();
+        let mut buffer_reader = UserSlice::new(info.data_ptr, data_size).reader();
         let mut end_of_previous_object = 0;
         let mut sg_state = None;
 
         // Copy offsets if there are any.
         if offsets_size > 0 {
-            let mut offsets_reader =
-                UserSlice::new(UserPtr::from_addr(trd_data_ptr.offsets as _), offsets_size)
-                    .reader();
+            let mut offsets_reader = UserSlice::new(info.offsets_ptr, offsets_size).reader();
 
             let offsets_start = aligned_data_size;
             let offsets_end = aligned_data_size + offsets_size;
@@ -1192,37 +1190,92 @@ fn top_of_transaction_stack(&self) -> Result<Option<DArc<Transaction>>> {
         }
     }
 
-    fn transaction<T>(self: &Arc<Self>, tr: &BinderTransactionDataSg, inner: T)
-    where
-        T: FnOnce(&Arc<Self>, &BinderTransactionDataSg) -> BinderResult,
-    {
-        if let Err(err) = inner(self, tr) {
-            if err.should_pr_warn() {
-                let mut ee = self.inner.lock().extended_error;
-                ee.command = err.reply;
-                ee.param = err.as_errno();
-                pr_warn!(
-                    "Transaction failed: {:?} my_pid:{}",
-                    err,
-                    self.process.pid_in_current_ns()
-                );
+    // No inlining avoids allocating stack space for `BinderTransactionData` for the entire
+    // duration of `transaction()`.
+    #[inline(never)]
+    fn read_transaction_info(
+        &self,
+        cmd: u32,
+        reader: &mut UserSliceReader,
+        info: &mut TransactionInfo,
+    ) -> Result<()> {
+        let td = match cmd {
+            BC_TRANSACTION | BC_REPLY => {
+                reader.read::<BinderTransactionData>()?.with_buffers_size(0)
+            }
+            BC_TRANSACTION_SG | BC_REPLY_SG => reader.read::<BinderTransactionDataSg>()?,
+            _ => return Err(EINVAL),
+        };
+
+        // SAFETY: Above `read` call initializes all bytes, so this union read is ok.
+        let trd_data_ptr = unsafe { &td.transaction_data.data.ptr };
+
+        info.is_reply = matches!(cmd, BC_REPLY | BC_REPLY_SG);
+        info.from_pid = self.process.task.pid();
+        info.from_tid = self.id;
+        info.code = td.transaction_data.code;
+        info.flags = td.transaction_data.flags;
+        info.data_ptr = UserPtr::from_addr(trd_data_ptr.buffer as usize);
+        info.data_size = td.transaction_data.data_size as usize;
+        info.offsets_ptr = UserPtr::from_addr(trd_data_ptr.offsets as usize);
+        info.offsets_size = td.transaction_data.offsets_size as usize;
+        info.buffers_size = td.buffers_size as usize;
+        // SAFETY: Above `read` call initializes all bytes, so this union read is ok.
+        info.target_handle = unsafe { td.transaction_data.target.handle };
+        Ok(())
+    }
+
+    #[inline(never)]
+    fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Result<()> {
+        let mut info = TransactionInfo::zeroed();
+        self.read_transaction_info(cmd, reader, &mut info)?;
+
+        let ret = if info.is_reply {
+            self.reply_inner(&mut info)
+        } else if info.is_oneway() {
+            self.oneway_transaction_inner(&mut info)
+        } else {
+            self.transaction_inner(&mut info)
+        };
+
+        if let Err(err) = ret {
+            if err.reply != BR_TRANSACTION_COMPLETE {
+                info.reply = err.reply;
             }
 
             self.push_return_work(err.reply);
+            if let Some(source) = &err.source {
+                info.errno = source.to_errno();
+                info.reply = err.reply;
+
+                {
+                    let mut ee = self.inner.lock().extended_error;
+                    ee.command = err.reply;
+                    ee.param = source.to_errno();
+                }
+
+                pr_warn!(
+                    "{}:{} transaction to {} failed: {source:?}",
+                    info.from_pid,
+                    info.from_tid,
+                    info.to_pid
+                );
+            }
         }
+
+        Ok(())
     }
 
-    fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
-        // SAFETY: Handle's type has no invalid bit patterns.
-        let handle = unsafe { tr.transaction_data.target.handle };
-        let node_ref = self.process.get_transaction_node(handle)?;
+    fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
+        let node_ref = self.process.get_transaction_node(info.target_handle)?;
+        info.to_pid = node_ref.node.owner.task.pid();
         security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
         // TODO: We need to ensure that there isn't a pending transaction in the work queue. How
         // could this happen?
         let top = self.top_of_transaction_stack()?;
         let list_completion = DTRWrap::arc_try_new(DeliverCode::new(BR_TRANSACTION_COMPLETE))?;
         let completion = list_completion.clone_arc();
-        let transaction = Transaction::new(node_ref, top, self, tr)?;
+        let transaction = Transaction::new(node_ref, top, self, info)?;
 
         // Check that the transaction stack hasn't changed while the lock was released, then update
         // it with the new transaction.
@@ -1238,7 +1291,7 @@ fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderRe
             inner.push_work_deferred(list_completion);
         }
 
-        if let Err(e) = transaction.submit() {
+        if let Err(e) = transaction.submit(info) {
             completion.skip();
             // Define `transaction` first to drop it after `inner`.
             let transaction;
@@ -1251,18 +1304,21 @@ fn transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderRe
         }
     }
 
-    fn reply_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
+    fn reply_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
         let orig = self.inner.lock().pop_transaction_to_reply(self)?;
         if !orig.from.is_current_transaction(&orig) {
             return Err(EINVAL.into());
         }
 
+        info.to_tid = orig.from.id;
+        info.to_pid = orig.from.process.task.pid();
+
         // We need to complete the transaction even if we cannot complete building the reply.
         let out = (|| -> BinderResult<_> {
             let completion = DTRWrap::arc_try_new(DeliverCode::new(BR_TRANSACTION_COMPLETE))?;
             let process = orig.from.process.clone();
             let allow_fds = orig.flags & TF_ACCEPT_FDS != 0;
-            let reply = Transaction::new_reply(self, process, tr, allow_fds)?;
+            let reply = Transaction::new_reply(self, process, info, allow_fds)?;
             self.inner.lock().push_work(completion);
             orig.from.deliver_reply(Ok(reply), &orig);
             Ok(())
@@ -1283,16 +1339,12 @@ fn reply_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
         out
     }
 
-    fn oneway_transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> BinderResult {
-        // SAFETY: The `handle` field is valid for all possible byte values, so reading from the
-        // union is okay.
-        let handle = unsafe { tr.transaction_data.target.handle };
-        let node_ref = self.process.get_transaction_node(handle)?;
+    fn oneway_transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult {
+        let node_ref = self.process.get_transaction_node(info.target_handle)?;
+        info.to_pid = node_ref.node.owner.task.pid();
         security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?;
-        let transaction = Transaction::new(node_ref, None, self, tr)?;
-        let code = if self.process.is_oneway_spam_detection_enabled()
-            && transaction.oneway_spam_detected
-        {
+        let transaction = Transaction::new(node_ref, None, self, info)?;
+        let code = if self.process.is_oneway_spam_detection_enabled() && info.oneway_spam_suspect {
             BR_ONEWAY_SPAM_SUSPECT
         } else {
             BR_TRANSACTION_COMPLETE
@@ -1300,7 +1352,7 @@ fn oneway_transaction_inner(self: &Arc<Self>, tr: &BinderTransactionDataSg) -> B
         let list_completion = DTRWrap::arc_try_new(DeliverCode::new(code))?;
         let completion = list_completion.clone_arc();
         self.inner.lock().push_work(list_completion);
-        match transaction.submit() {
+        match transaction.submit(info) {
             Ok(()) => Ok(()),
             Err(err) => {
                 completion.skip();
@@ -1318,32 +1370,12 @@ fn write(self: &Arc<Self>, req: &mut BinderWriteRead) -> Result {
         while reader.len() >= size_of::<u32>() && self.inner.lock().return_work.is_unused() {
             let before = reader.len();
             let cmd = reader.read::<u32>()?;
+            crate::trace::trace_command(cmd);
             GLOBAL_STATS.inc_bc(cmd);
             self.process.stats.inc_bc(cmd);
             match cmd {
-                BC_TRANSACTION => {
-                    let tr = reader.read::<BinderTransactionData>()?.with_buffers_size(0);
-                    if tr.transaction_data.flags & TF_ONE_WAY != 0 {
-                        self.transaction(&tr, Self::oneway_transaction_inner);
-                    } else {
-                        self.transaction(&tr, Self::transaction_inner);
-                    }
-                }
-                BC_TRANSACTION_SG => {
-                    let tr = reader.read::<BinderTransactionDataSg>()?;
-                    if tr.transaction_data.flags & TF_ONE_WAY != 0 {
-                        self.transaction(&tr, Self::oneway_transaction_inner);
-                    } else {
-                        self.transaction(&tr, Self::transaction_inner);
-                    }
-                }
-                BC_REPLY => {
-                    let tr = reader.read::<BinderTransactionData>()?.with_buffers_size(0);
-                    self.transaction(&tr, Self::reply_inner)
-                }
-                BC_REPLY_SG => {
-                    let tr = reader.read::<BinderTransactionDataSg>()?;
-                    self.transaction(&tr, Self::reply_inner)
+                BC_TRANSACTION | BC_TRANSACTION_SG | BC_REPLY | BC_REPLY_SG => {
+                    self.transaction(cmd, &mut reader)?;
                 }
                 BC_FREE_BUFFER => {
                     let buffer = self.process.buffer_get(reader.read()?);
@@ -1407,11 +1439,18 @@ fn read(self: &Arc<Self>, req: &mut BinderWriteRead, wait: bool) -> Result {
             UserSlice::new(UserPtr::from_addr(read_start as _), read_len as _).writer(),
             self,
         );
-        let (in_pool, use_proc_queue) = {
+        let (in_pool, has_transaction, thread_todo, use_proc_queue) = {
             let inner = self.inner.lock();
-            (inner.is_looper(), inner.should_use_process_work_queue())
+            (
+                inner.is_looper(),
+                inner.current_transaction.is_some(),
+                !inner.work_list.is_empty(),
+                inner.should_use_process_work_queue(),
+            )
         };
 
+        crate::trace::trace_wait_for_work(use_proc_queue, has_transaction, thread_todo);
+
         let getter = if use_proc_queue {
             Self::get_work
         } else {
@@ -1477,6 +1516,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
         let mut ret = Ok(());
         if req.write_size > 0 {
             ret = self.write(&mut req);
+            crate::trace::trace_write_done(ret);
             if let Err(err) = ret {
                 pr_warn!(
                     "Write failure {:?} in pid:{}",
@@ -1493,6 +1533,7 @@ pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Resul
         // Go through the work queue.
         if req.read_size > 0 {
             ret = self.read(&mut req, wait);
+            crate::trace::trace_read_done(ret);
             if ret.is_err() && ret != Err(EINTR) {
                 pr_warn!(
                     "Read failure {:?} in pid:{}",
diff --git a/drivers/android/binder/trace.rs b/drivers/android/binder/trace.rs
index 9839901..5539672 100644
--- a/drivers/android/binder/trace.rs
+++ b/drivers/android/binder/trace.rs
@@ -5,13 +5,23 @@
 use crate::transaction::Transaction;
 
 use kernel::bindings::{rust_binder_transaction, task_struct};
-use kernel::ffi::{c_uint, c_ulong};
+use kernel::error::Result;
+use kernel::ffi::{c_int, c_uint, c_ulong};
 use kernel::task::Task;
 use kernel::tracepoint::declare_trace;
 
 declare_trace! {
-    unsafe fn rust_binder_ioctl(cmd: c_uint, arg: c_ulong);
-    unsafe fn rust_binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
+    unsafe fn binder_ioctl(cmd: c_uint, arg: c_ulong);
+    unsafe fn binder_ioctl_done(ret: c_int);
+    unsafe fn binder_read_done(ret: c_int);
+    unsafe fn binder_write_done(ret: c_int);
+    unsafe fn binder_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool);
+    unsafe fn binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct);
+    unsafe fn binder_transaction_received(t: rust_binder_transaction);
+    unsafe fn binder_transaction_fd_send(t_debug_id: c_int, fd: c_int, offset: usize);
+    unsafe fn binder_transaction_fd_recv(t_debug_id: c_int, fd: c_int, offset: usize);
+    unsafe fn binder_command(cmd: u32);
+    unsafe fn binder_return(ret: u32);
 }
 
 #[inline]
@@ -20,9 +30,39 @@ fn raw_transaction(t: &Transaction) -> rust_binder_transaction {
 }
 
 #[inline]
+fn to_errno(ret: Result) -> i32 {
+    match ret {
+        Ok(()) => 0,
+        Err(err) => err.to_errno(),
+    }
+}
+
+#[inline]
 pub(crate) fn trace_ioctl(cmd: u32, arg: usize) {
     // SAFETY: Always safe to call.
-    unsafe { rust_binder_ioctl(cmd, arg as c_ulong) }
+    unsafe { binder_ioctl(cmd, arg as c_ulong) }
+}
+
+#[inline]
+pub(crate) fn trace_ioctl_done(ret: Result) {
+    // SAFETY: Always safe to call.
+    unsafe { binder_ioctl_done(to_errno(ret)) }
+}
+#[inline]
+pub(crate) fn trace_read_done(ret: Result) {
+    // SAFETY: Always safe to call.
+    unsafe { binder_read_done(to_errno(ret)) }
+}
+#[inline]
+pub(crate) fn trace_write_done(ret: Result) {
+    // SAFETY: Always safe to call.
+    unsafe { binder_write_done(to_errno(ret)) }
+}
+
+#[inline]
+pub(crate) fn trace_wait_for_work(proc_work: bool, transaction_stack: bool, thread_todo: bool) {
+    // SAFETY: Always safe to call.
+    unsafe { binder_wait_for_work(proc_work, transaction_stack, thread_todo) }
 }
 
 #[inline]
@@ -33,5 +73,33 @@ pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Ta
     };
     // SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is
     // valid or null.
-    unsafe { rust_binder_transaction(reply, raw_transaction(t), thread) }
+    unsafe { binder_transaction(reply, raw_transaction(t), thread) }
+}
+
+#[inline]
+pub(crate) fn trace_transaction_received(t: &Transaction) {
+    // SAFETY: The raw transaction is valid for the duration of this call.
+    unsafe { binder_transaction_received(raw_transaction(t)) }
+}
+
+#[inline]
+pub(crate) fn trace_transaction_fd_send(t_debug_id: usize, fd: u32, offset: usize) {
+    // SAFETY: This function is always safe to call.
+    unsafe { binder_transaction_fd_send(t_debug_id as c_int, fd as c_int, offset) }
+}
+#[inline]
+pub(crate) fn trace_transaction_fd_recv(t_debug_id: usize, fd: u32, offset: usize) {
+    // SAFETY: This function is always safe to call.
+    unsafe { binder_transaction_fd_recv(t_debug_id as c_int, fd as c_int, offset) }
+}
+
+#[inline]
+pub(crate) fn trace_command(cmd: u32) {
+    // SAFETY: This function is always safe to call.
+    unsafe { binder_command(cmd) }
+}
+#[inline]
+pub(crate) fn trace_return(ret: u32) {
+    // SAFETY: This function is always safe to call.
+    unsafe { binder_return(ret) }
 }
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index 75e6f5f..47d5e4d 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -8,7 +8,7 @@
     seq_print,
     sync::atomic::{ordering::Relaxed, Atomic},
     sync::{Arc, SpinLock},
-    task::Kuid,
+    task::{Kuid, Pid},
     time::{Instant, Monotonic},
     types::ScopeGuard,
 };
@@ -24,6 +24,33 @@
     BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead,
 };
 
+#[derive(Zeroable)]
+pub(crate) struct TransactionInfo {
+    pub(crate) from_pid: Pid,
+    pub(crate) from_tid: Pid,
+    pub(crate) to_pid: Pid,
+    pub(crate) to_tid: Pid,
+    pub(crate) code: u32,
+    pub(crate) flags: u32,
+    pub(crate) data_ptr: UserPtr,
+    pub(crate) data_size: usize,
+    pub(crate) offsets_ptr: UserPtr,
+    pub(crate) offsets_size: usize,
+    pub(crate) buffers_size: usize,
+    pub(crate) target_handle: u32,
+    pub(crate) errno: i32,
+    pub(crate) reply: u32,
+    pub(crate) oneway_spam_suspect: bool,
+    pub(crate) is_reply: bool,
+}
+
+impl TransactionInfo {
+    #[inline]
+    pub(crate) fn is_oneway(&self) -> bool {
+        self.flags & TF_ONE_WAY != 0
+    }
+}
+
 use core::mem::offset_of;
 use kernel::bindings::rb_transaction_layout;
 pub(crate) const TRANSACTION_LAYOUT: rb_transaction_layout = rb_transaction_layout {
@@ -52,7 +79,6 @@ pub(crate) struct Transaction {
     data_address: usize,
     sender_euid: Kuid,
     txn_security_ctx_off: Option<usize>,
-    pub(crate) oneway_spam_detected: bool,
     start_time: Instant<Monotonic>,
 }
 
@@ -65,17 +91,16 @@ pub(crate) fn new(
         node_ref: NodeRef,
         from_parent: Option<DArc<Transaction>>,
         from: &Arc<Thread>,
-        tr: &BinderTransactionDataSg,
+        info: &mut TransactionInfo,
     ) -> BinderResult<DLArc<Self>> {
         let debug_id = super::next_debug_id();
-        let trd = &tr.transaction_data;
         let allow_fds = node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_FDS != 0;
         let txn_security_ctx = node_ref.node.flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX != 0;
         let mut txn_security_ctx_off = if txn_security_ctx { Some(0) } else { None };
         let to = node_ref.node.owner.clone();
         let mut alloc = match from.copy_transaction_data(
             to.clone(),
-            tr,
+            info,
             debug_id,
             allow_fds,
             txn_security_ctx_off.as_mut(),
@@ -88,15 +113,14 @@ pub(crate) fn new(
                 return Err(err);
             }
         };
-        let oneway_spam_detected = alloc.oneway_spam_detected;
-        if trd.flags & TF_ONE_WAY != 0 {
+        if info.is_oneway() {
             if from_parent.is_some() {
                 pr_warn!("Oneway transaction should not be in a transaction stack.");
                 return Err(EINVAL.into());
             }
             alloc.set_info_oneway_node(node_ref.node.clone());
         }
-        if trd.flags & TF_CLEAR_BUF != 0 {
+        if info.flags & TF_CLEAR_BUF != 0 {
             alloc.set_info_clear_on_drop();
         }
         let target_node = node_ref.node.clone();
@@ -107,18 +131,17 @@ pub(crate) fn new(
             debug_id,
             target_node: Some(target_node),
             from_parent,
-            sender_euid: from.process.task.euid(),
+            sender_euid: Kuid::current_euid(),
             from: from.clone(),
             to,
-            code: trd.code,
-            flags: trd.flags,
-            data_size: trd.data_size as _,
-            offsets_size: trd.offsets_size as _,
+            code: info.code,
+            flags: info.flags,
+            data_size: info.data_size,
+            offsets_size: info.offsets_size,
             data_address,
             allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
             is_outstanding: Atomic::new(false),
             txn_security_ctx_off,
-            oneway_spam_detected,
             start_time: Instant::now(),
         }))?)
     }
@@ -126,39 +149,36 @@ pub(crate) fn new(
     pub(crate) fn new_reply(
         from: &Arc<Thread>,
         to: Arc<Process>,
-        tr: &BinderTransactionDataSg,
+        info: &mut TransactionInfo,
         allow_fds: bool,
     ) -> BinderResult<DLArc<Self>> {
         let debug_id = super::next_debug_id();
-        let trd = &tr.transaction_data;
-        let mut alloc = match from.copy_transaction_data(to.clone(), tr, debug_id, allow_fds, None)
-        {
-            Ok(alloc) => alloc,
-            Err(err) => {
-                pr_warn!("Failure in copy_transaction_data: {:?}", err);
-                return Err(err);
-            }
-        };
-        let oneway_spam_detected = alloc.oneway_spam_detected;
-        if trd.flags & TF_CLEAR_BUF != 0 {
+        let mut alloc =
+            match from.copy_transaction_data(to.clone(), info, debug_id, allow_fds, None) {
+                Ok(alloc) => alloc,
+                Err(err) => {
+                    pr_warn!("Failure in copy_transaction_data: {:?}", err);
+                    return Err(err);
+                }
+            };
+        if info.flags & TF_CLEAR_BUF != 0 {
             alloc.set_info_clear_on_drop();
         }
         Ok(DTRWrap::arc_pin_init(pin_init!(Transaction {
             debug_id,
             target_node: None,
             from_parent: None,
-            sender_euid: from.process.task.euid(),
+            sender_euid: Kuid::current_euid(),
             from: from.clone(),
             to,
-            code: trd.code,
-            flags: trd.flags,
-            data_size: trd.data_size as _,
-            offsets_size: trd.offsets_size as _,
+            code: info.code,
+            flags: info.flags,
+            data_size: info.data_size,
+            offsets_size: info.offsets_size,
             data_address: alloc.ptr,
             allocation <- kernel::new_spinlock!(Some(alloc.success()), "Transaction::new"),
             is_outstanding: Atomic::new(false),
             txn_security_ctx_off: None,
-            oneway_spam_detected,
             start_time: Instant::now(),
         }))?)
     }
@@ -248,7 +268,7 @@ fn drop_outstanding_txn(&self) {
     /// stack, otherwise uses the destination process.
     ///
     /// Not used for replies.
-    pub(crate) fn submit(self: DLArc<Self>) -> BinderResult {
+    pub(crate) fn submit(self: DLArc<Self>, info: &mut TransactionInfo) -> BinderResult {
         // Defined before `process_inner` so that the destructor runs after releasing the lock.
         let mut _t_outdated;
 
@@ -298,6 +318,7 @@ pub(crate) fn submit(self: DLArc<Self>) -> BinderResult {
         }
 
         let res = if let Some(thread) = self.find_target_thread() {
+            info.to_tid = thread.id;
             crate::trace::trace_transaction(false, &self, Some(&thread.task));
             match thread.push_work(self) {
                 PushWorkRes::Ok => Ok(()),
@@ -430,6 +451,8 @@ fn do_work(
 
         self.drop_outstanding_txn();
 
+        crate::trace::trace_transaction_received(&self);
+
         // When this is not a reply and not a oneway transaction, update `current_transaction`. If
         // it's a reply, `current_transaction` has already been updated appropriately.
         if self.target_node.is_some() && tr_sec.transaction_data.flags & TF_ONE_WAY == 0 {
diff --git a/drivers/atm/.gitignore b/drivers/atm/.gitignore
deleted file mode 100644
index ddd374e..0000000
--- a/drivers/atm/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-fore200e_mkfirm
-fore200e_pca_fw.c
-pca200e.bin
-pca200e_ecd.bin2
diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 63cdb46..cb1dd77 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -15,306 +15,6 @@
 
 if ATM_DRIVERS && NETDEVICES && ATM
 
-config ATM_DUMMY
-	tristate "Dummy ATM driver"
-	help
-	  Dummy ATM driver. Useful for proxy signalling, testing,
-	  and development.  If unsure, say N.
-
-config ATM_TCP
-	tristate "ATM over TCP"
-	depends on INET
-	help
-	  ATM over TCP driver. Useful mainly for development and for
-	  experiments. If unsure, say N.
-
-config ATM_LANAI
-	tristate "Efficient Networks Speedstream 3010"
-	depends on PCI && ATM
-	help
-	  Supports ATM cards based on the Efficient Networks "Lanai"
-	  chipset such as the Speedstream 3010 and the ENI-25p.  The
-	  Speedstream 3060 is currently not supported since we don't
-	  have the code to drive the on-board Alcatel DSL chipset (yet).
-
-config ATM_ENI
-	tristate "Efficient Networks ENI155P"
-	depends on PCI
-	help
-	  Driver for the Efficient Networks ENI155p series and SMC ATM
-	  Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
-	  2MB on-board RAM (Efficient calls them "C" and "S", respectively),
-	  and the FPGA and the ASIC Tonga versions of the board are supported.
-	  The driver works with MMF (-MF or ...F) and UTP-5 (-U5 or ...D)
-	  adapters.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called eni.
-
-config ATM_ENI_DEBUG
-	bool "Enable extended debugging"
-	depends on ATM_ENI
-	help
-	  Extended debugging records various events and displays that list
-	  when an inconsistency is detected. This mechanism is faster than
-	  generally using printks, but still has some impact on performance.
-	  Note that extended debugging may create certain race conditions
-	  itself. Enable this ONLY if you suspect problems with the driver.
-
-config ATM_ENI_TUNE_BURST
-	bool "Fine-tune burst settings"
-	depends on ATM_ENI
-	help
-	  In order to obtain good throughput, the ENI NIC can transfer
-	  multiple words of data per PCI bus access cycle. Such a multi-word
-	  transfer is called a burst.
-
-	  The default settings for the burst sizes are suitable for most PCI
-	  chipsets. However, in some cases, large bursts may overrun buffers
-	  in the PCI chipset and cause data corruption. In such cases, large
-	  bursts must be disabled and only (slower) small bursts can be used.
-	  The burst sizes can be set independently in the send (TX) and
-	  receive (RX) direction.
-
-	  Note that enabling many different burst sizes in the same direction
-	  may increase the cost of setting up a transfer such that the
-	  resulting throughput is lower than when using only the largest
-	  available burst size.
-
-	  Also, sometimes larger bursts lead to lower throughput, e.g. on an
-	  Intel 440FX board, a drop from 135 Mbps to 103 Mbps was observed
-	  when going from 8W to 16W bursts.
-
-config ATM_ENI_BURST_TX_16W
-	bool "Enable 16W TX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst sixteen words at once in the send direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets.
-
-config ATM_ENI_BURST_TX_8W
-	bool "Enable 8W TX bursts (recommended)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst eight words at once in the send direction. This is the default
-	  setting.
-
-config ATM_ENI_BURST_TX_4W
-	bool "Enable 4W TX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst four words at once in the send direction. You may want to try
-	  this if you have disabled 8W bursts. Enabling 4W if 8W is also set
-	  may or may not improve throughput.
-
-config ATM_ENI_BURST_TX_2W
-	bool "Enable 2W TX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst two words at once in the send direction. You may want to try
-	  this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or 8W
-	  are also set may or may not improve throughput.
-
-config ATM_ENI_BURST_RX_16W
-	bool "Enable 16W RX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst sixteen words at once in the receive direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets.
-
-config ATM_ENI_BURST_RX_8W
-	bool "Enable 8W RX bursts (discouraged)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst eight words at once in the receive direction. This may work
-	  with recent PCI chipsets, but is known to fail with older chipsets,
-	  such as the Intel Neptune series.
-
-config ATM_ENI_BURST_RX_4W
-	bool "Enable 4W RX bursts (recommended)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst four words at once in the receive direction. This is the
-	  default setting. Enabling 4W if 8W is also set may or may not
-	  improve throughput.
-
-config ATM_ENI_BURST_RX_2W
-	bool "Enable 2W RX bursts (optional)"
-	depends on ATM_ENI_TUNE_BURST
-	help
-	  Burst two words at once in the receive direction. You may want to
-	  try this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or
-	  8W are also set may or may not improve throughput.
-
-config ATM_NICSTAR
-	tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
-	depends on PCI
-	help
-	  The NICStAR chipset family is used in a large number of ATM NICs for
-	  25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
-	  series. Say Y if you have one of those.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called nicstar.
-
-config ATM_NICSTAR_USE_SUNI
-	bool "Use suni PHY driver (155Mbps)"
-	depends on ATM_NICSTAR
-	help
-	  Support for the S-UNI and compatible PHYsical layer chips. These are
-	  found in most 155Mbps NICStAR based ATM cards, namely in the
-	  ForeRunner LE155 cards. This driver provides detection of cable~
-	  removal and reinsertion and provides some statistics. This driver
-	  doesn't have removal capability when compiled as a module, so if you
-	  need that capability don't include S-UNI support (it's not needed to
-	  make the card work).
-
-config ATM_NICSTAR_USE_IDT77105
-	bool "Use IDT77105 PHY driver (25Mbps)"
-	depends on ATM_NICSTAR
-	help
-	  Support for the PHYsical layer chip in ForeRunner LE25 cards. In
-	  addition to cable removal/reinsertion detection, this driver allows
-	  you to control the loopback mode of the chip via a dedicated IOCTL.
-	  This driver is required for proper handling of temporary carrier
-	  loss, so if you have a 25Mbps NICStAR based ATM card you must say Y.
-
-config ATM_IDT77252
-	tristate "IDT 77252 (NICStAR II)"
-	depends on PCI
-	help
-	  Driver for the IDT 77252 ATM PCI chips.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called idt77252.
-
-config ATM_IDT77252_DEBUG
-	bool "Enable debugging messages"
-	depends on ATM_IDT77252
-	help
-	  Somewhat useful debugging messages are available. The choice of
-	  messages is controlled by a bitmap.  This may be specified as a
-	  module argument.  See the file <file:drivers/atm/idt77252.h> for
-	  the meanings of the bits in the mask.
-
-	  When active, these messages can have a significant impact on the
-	  speed of the driver, and the size of your syslog files! When
-	  inactive, they will have only a modest impact on performance.
-
-config ATM_IDT77252_RCV_ALL
-	bool "Receive ALL cells in raw queue"
-	depends on ATM_IDT77252
-	help
-	  Enable receiving of all cells on the ATM link, that do not match
-	  an open connection in the raw cell queue of the driver.  Useful
-	  for debugging or special applications only, so the safe answer is N.
-
-config ATM_IDT77252_USE_SUNI
-	bool
-	depends on ATM_IDT77252
-	default y
-
-config ATM_IA
-	tristate "Interphase ATM PCI x575/x525/x531"
-	depends on PCI
-	help
-	  This is a driver for the Interphase (i)ChipSAR adapter cards
-	  which include a variety of variants in term of the size of the
-	  control memory (128K-1KVC, 512K-4KVC), the size of the packet
-	  memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3,
-	  UTP155, UTP25, DS3 and E3). Go to:
-	  	<http://www.iphase.com/>
-	  for more info about the cards. Say Y (or M to compile as a module
-	  named iphase) here if you have one of these cards.
-
-	  See the file
-	  <file:Documentation/networking/device_drivers/atm/iphase.rst>
-	  for further details.
-
-config ATM_IA_DEBUG
-	bool "Enable debugging messages"
-	depends on ATM_IA
-	help
-	  Somewhat useful debugging messages are available. The choice of
-	  messages is controlled by a bitmap. This may be specified as a
-	  module argument (kernel command line argument as well?), changed
-	  dynamically using an ioctl (Get the debug utility, iadbg, from
-	  <ftp://ftp.iphase.com/pub/atm/pci/>).
-
-	  See the file <file:drivers/atm/iphase.h> for the meanings of the
-	  bits in the mask.
-
-	  When active, these messages can have a significant impact on the
-	  speed of the driver, and the size of your syslog files! When
-	  inactive, they will have only a modest impact on performance.
-
-config ATM_FORE200E
-	tristate "FORE Systems 200E-series"
-	depends on (PCI || SBUS)
-	select FW_LOADER
-	help
-	  This is a driver for the FORE Systems 200E-series ATM adapter
-	  cards. It simultaneously supports PCA-200E and SBA-200E models
-	  on PCI and SBUS hosts. Say Y (or M to compile as a module
-	  named fore_200e) here if you have one of these ATM adapters.
-
-	  See the file
-	  <file:Documentation/networking/device_drivers/atm/fore200e.rst> for
-	  further details.
-
-config ATM_FORE200E_USE_TASKLET
-	bool "Defer interrupt work to a tasklet"
-	depends on ATM_FORE200E
-	default n
-	help
-	  This defers work to be done by the interrupt handler to a
-	  tasklet instead of handling everything at interrupt time.  This
-	  may improve the responsive of the host.
-
-config ATM_FORE200E_TX_RETRY
-	int "Maximum number of tx retries"
-	depends on ATM_FORE200E
-	default "16"
-	help
-	  Specifies the number of times the driver attempts to transmit
-	  a message before giving up, if the transmit queue of the ATM card
-	  is transiently saturated.
-
-	  Saturation of the transmit queue may occur only under extreme
-	  conditions, e.g. when a fast host continuously submits very small
-	  frames (<64 bytes) or raw AAL0 cells (48 bytes) to the ATM adapter.
-
-	  Note that under common conditions, it is unlikely that you encounter
-	  a saturation of the transmit queue, so the retry mechanism never
-	  comes into play.
-
-config ATM_FORE200E_DEBUG
-	int "Debugging level (0-3)"
-	depends on ATM_FORE200E
-	default "0"
-	help
-	  Specifies the level of debugging messages issued by the driver.
-	  The verbosity of the driver increases with the value of this
-	  parameter.
-
-	  When active, these messages can have a significant impact on
-	  the performances of the driver, and the size of your syslog files!
-	  Keep the debugging level to 0 during normal operations.
-
-config ATM_HE
-	tristate "ForeRunner HE Series"
-	depends on PCI
-	help
-	  This is a driver for the Marconi ForeRunner HE-series ATM adapter
-	  cards. It simultaneously supports the 155 and 622 versions.
-
-config ATM_HE_USE_SUNI
-	bool "Use S/UNI PHY driver"
-	depends on ATM_HE
-	help
-	  Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
-	  HE cards.  This driver provides carrier detection some statistics.
-
 config ATM_SOLOS
 	tristate "Solos ADSL2+ PCI Multiport card driver"
 	depends on PCI
diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile
index c9eade9..b95125a 100644
--- a/drivers/atm/Makefile
+++ b/drivers/atm/Makefile
@@ -1,32 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Linux network (ATM) device drivers.
-#
 
-fore_200e-y	:= fore200e.o
-
-obj-$(CONFIG_ATM_NICSTAR)	+= nicstar.o
-obj-$(CONFIG_ATM_IA)		+= iphase.o suni.o
-obj-$(CONFIG_ATM_FORE200E)	+= fore_200e.o
-obj-$(CONFIG_ATM_ENI)		+= eni.o suni.o
-obj-$(CONFIG_ATM_IDT77252)	+= idt77252.o
 obj-$(CONFIG_ATM_SOLOS)		+= solos-pci.o
-
-ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y)
-  obj-$(CONFIG_ATM_NICSTAR)	+= suni.o
-endif
-ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y)
-  obj-$(CONFIG_ATM_NICSTAR)	+= idt77105.o
-endif
-ifeq ($(CONFIG_ATM_IDT77252_USE_SUNI),y)
-  obj-$(CONFIG_ATM_IDT77252)	+= suni.o
-endif
-
-obj-$(CONFIG_ATM_DUMMY)		+= adummy.o
-obj-$(CONFIG_ATM_TCP)		+= atmtcp.o
-obj-$(CONFIG_ATM_LANAI)		+= lanai.o
-
-obj-$(CONFIG_ATM_HE)		+= he.o
-ifeq ($(CONFIG_ATM_HE_USE_SUNI),y)
-  obj-$(CONFIG_ATM_HE)		+= suni.o
-endif
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c
deleted file mode 100644
index c8d0053..0000000
--- a/drivers/atm/adummy.c
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * adummy.c: a dummy ATM driver
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/sonet.h>
-
-/* version definition */
-
-#define DRV_VERSION "1.0"
-
-#define DEV_LABEL "adummy"
-
-#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
-
-struct adummy_dev {
-	struct atm_dev *atm_dev;
-
-	struct list_head entry;
-};
-
-/* globals */
-
-static LIST_HEAD(adummy_devs);
-
-static ssize_t __set_signal(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
-	int signal;
-
-	if (sscanf(buf, "%d", &signal) == 1) {
-
-		if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND)
-			signal = ATM_PHY_SIG_UNKNOWN;
-
-		atm_dev_signal_change(atm_dev, signal);
-		return 1;
-	}
-	return -EINVAL;
-}
-
-static ssize_t __show_signal(struct device *dev,
-	struct device_attribute *attr, char *buf)
-{
-	struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
-	return sprintf(buf, "%d\n", atm_dev->signal);
-}
-static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal);
-
-static struct attribute *adummy_attrs[] = {
-	&dev_attr_signal.attr,
-	NULL
-};
-
-static const struct attribute_group adummy_group_attrs = {
-	.name = NULL, /* We want them in dev's root folder */
-	.attrs = adummy_attrs
-};
-
-static int __init
-adummy_start(struct atm_dev *dev)
-{
-	dev->ci_range.vpi_bits = 4;
-	dev->ci_range.vci_bits = 12;
-
-	return 0;
-}
-
-static int
-adummy_open(struct atm_vcc *vcc)
-{
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
-		return 0;
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	return 0;
-}
-
-static void
-adummy_close(struct atm_vcc *vcc)
-{
-	clear_bit(ATM_VF_READY, &vcc->flags);
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-}
-
-static int
-adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	if (vcc->pop)
-		vcc->pop(vcc, skb);
-	else
-		dev_kfree_skb_any(skb);
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int
-adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
-{
-	int left = *pos;
-
-	if (!left--)
-		return sprintf(page, "version %s\n", DRV_VERSION);
-
-	return 0;
-}
-
-static const struct atmdev_ops adummy_ops =
-{
-	.open =		adummy_open,
-	.close =	adummy_close,	
-	.send =		adummy_send,
-	.proc_read =	adummy_proc_read,
-	.owner =	THIS_MODULE
-};
-
-static int __init adummy_init(void)
-{
-	struct atm_dev *atm_dev;
-	struct adummy_dev *adummy_dev;
-	int err = 0;
-
-	printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
-
-	adummy_dev = kzalloc_obj(struct adummy_dev);
-	if (!adummy_dev) {
-		printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
-		err = -ENOMEM;
-		goto out;
-	}
-	atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
-	if (!atm_dev) {
-		printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
-		err = -ENODEV;
-		goto out_kfree;
-	}
-
-	adummy_dev->atm_dev = atm_dev;
-	atm_dev->dev_data = adummy_dev;
-
-	if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs))
-		dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n");
-
-	if (adummy_start(atm_dev)) {
-		printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
-		err = -ENODEV;
-		goto out_unregister;
-	}
-
-	list_add(&adummy_dev->entry, &adummy_devs);
-out:
-	return err;
-
-out_unregister:
-	atm_dev_deregister(atm_dev);
-out_kfree:
-	kfree(adummy_dev);
-	goto out;
-}
-
-static void __exit adummy_cleanup(void)
-{
-	struct adummy_dev *adummy_dev, *next;
-
-	list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
-		atm_dev_deregister(adummy_dev->atm_dev);
-		kfree(adummy_dev);
-	}
-}
-
-module_init(adummy_init);
-module_exit(adummy_cleanup);
-
-MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
-MODULE_DESCRIPTION("dummy ATM driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
deleted file mode 100644
index 9671985..0000000
--- a/drivers/atm/atmtcp.c
+++ /dev/null
@@ -1,513 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
-
-/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-
-#include <linux/module.h>
-#include <linux/wait.h>
-#include <linux/atmdev.h>
-#include <linux/atm_tcp.h>
-#include <linux/bitops.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-
-extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
-
-
-#define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
-
-
-struct atmtcp_dev_data {
-	struct atm_vcc *vcc;	/* control VCC; NULL if detached */
-	int persist;		/* non-zero if persistent */
-};
-
-
-#define DEV_LABEL    "atmtcp"
-
-#define MAX_VPI_BITS  8	/* simplifies life */
-#define MAX_VCI_BITS 16
-
-
-/*
- * Hairy code ahead: the control VCC may be closed while we're still
- * waiting for an answer, so we need to re-validate out_vcc every once
- * in a while.
- */
-
-
-static int atmtcp_send_control(struct atm_vcc *vcc,int type,
-    const struct atmtcp_control *msg,int flag)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	struct atm_vcc *out_vcc;
-	struct sk_buff *skb;
-	struct atmtcp_control *new_msg;
-	int old_test;
-	int error = 0;
-
-	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-	if (!out_vcc) return -EUNATCH;
-	skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
-	if (!skb) return -ENOMEM;
-	mb();
-	out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-	if (!out_vcc) {
-		dev_kfree_skb(skb);
-		return -EUNATCH;
-	}
-	atm_force_charge(out_vcc,skb->truesize);
-	new_msg = skb_put(skb, sizeof(*new_msg));
-	*new_msg = *msg;
-	new_msg->hdr.length = ATMTCP_HDR_MAGIC;
-	new_msg->type = type;
-	memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
-	*(struct atm_vcc **) &new_msg->vcc = vcc;
-	old_test = test_bit(flag,&vcc->flags);
-	out_vcc->push(out_vcc,skb);
-	add_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
-	while (test_bit(flag,&vcc->flags) == old_test) {
-		mb();
-		out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
-		if (!out_vcc) {
-			error = -EUNATCH;
-			break;
-		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule();
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
-	return error;
-}
-
-
-static int atmtcp_recv_control(const struct atmtcp_control *msg)
-{
-	struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
-
-	vcc->vpi = msg->addr.sap_addr.vpi;
-	vcc->vci = msg->addr.sap_addr.vci;
-	vcc->qos = msg->qos;
-	sk_atm(vcc)->sk_err = -msg->result;
-	switch (msg->type) {
-	    case ATMTCP_CTRL_OPEN:
-		change_bit(ATM_VF_READY,&vcc->flags);
-		break;
-	    case ATMTCP_CTRL_CLOSE:
-		change_bit(ATM_VF_ADDR,&vcc->flags);
-		break;
-	    default:
-		printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
-		    msg->type);
-		return -EINVAL;
-	}
-	wake_up(sk_sleep(sk_atm(vcc)));
-	return 0;
-}
-
-
-static void atmtcp_v_dev_close(struct atm_dev *dev)
-{
-	/* Nothing.... Isn't this simple :-)  -- REW */
-}
-
-
-static int atmtcp_v_open(struct atm_vcc *vcc)
-{
-	struct atmtcp_control msg;
-	int error;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	memset(&msg,0,sizeof(msg));
-	msg.addr.sap_family = AF_ATMPVC;
-	msg.hdr.vpi = htons(vpi);
-	msg.addr.sap_addr.vpi = vpi;
-	msg.hdr.vci = htons(vci);
-	msg.addr.sap_addr.vci = vci;
-	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
-	msg.type = ATMTCP_CTRL_OPEN;
-	msg.qos = vcc->qos;
-	set_bit(ATM_VF_ADDR,&vcc->flags);
-	clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
-	error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
-	if (error) return error;
-	return -sk_atm(vcc)->sk_err;
-}
-
-
-static void atmtcp_v_close(struct atm_vcc *vcc)
-{
-	struct atmtcp_control msg;
-
-	memset(&msg,0,sizeof(msg));
-	msg.addr.sap_family = AF_ATMPVC;
-	msg.addr.sap_addr.vpi = vcc->vpi;
-	msg.addr.sap_addr.vci = vcc->vci;
-	clear_bit(ATM_VF_READY,&vcc->flags);
-	(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
-}
-
-
-static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	struct atm_cirange ci;
-	struct atm_vcc *vcc;
-	struct sock *s;
-	int i;
-
-	if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
-	if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
-	if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
-	if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
-	if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
-	    ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
-	read_lock(&vcc_sklist_lock);
-	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
-		struct hlist_head *head = &vcc_hash[i];
-
-		sk_for_each(s, head) {
-			vcc = atm_sk(s);
-			if (vcc->dev != dev)
-				continue;
-			if ((vcc->vpi >> ci.vpi_bits) ||
-			    (vcc->vci >> ci.vci_bits)) {
-				read_unlock(&vcc_sklist_lock);
-				return -EBUSY;
-			}
-		}
-	}
-	read_unlock(&vcc_sklist_lock);
-	dev->ci_range = ci;
-	return 0;
-}
-
-
-static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	struct atmtcp_dev_data *dev_data;
-	struct atm_vcc *out_vcc=NULL; /* Initializer quietens GCC warning */
-	struct sk_buff *new_skb;
-	struct atmtcp_hdr *hdr;
-	int size;
-
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	dev_data = PRIV(vcc->dev);
-	if (dev_data) out_vcc = dev_data->vcc;
-	if (!dev_data || !out_vcc) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		if (dev_data) return 0;
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOLINK;
-	}
-	size = skb->len+sizeof(struct atmtcp_hdr);
-	new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
-	if (!new_skb) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOBUFS;
-	}
-	hdr = skb_put(new_skb, sizeof(struct atmtcp_hdr));
-	hdr->vpi = htons(vcc->vpi);
-	hdr->vci = htons(vcc->vci);
-	hdr->length = htonl(skb->len);
-	skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
-	if (vcc->pop) vcc->pop(vcc,skb);
-	else dev_kfree_skb(skb);
-	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
-	return 0;
-}
-
-
-static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
-{
-	struct atmtcp_dev_data *dev_data = PRIV(dev);
-
-	if (*pos) return 0;
-	if (!dev_data->persist) return sprintf(page,"ephemeral\n");
-	return sprintf(page,"persistent, %sconnected\n",
-	    dev_data->vcc ? "" : "dis");
-}
-
-
-static void atmtcp_c_close(struct atm_vcc *vcc)
-{
-	struct atm_dev *atmtcp_dev;
-	struct atmtcp_dev_data *dev_data;
-
-	atmtcp_dev = (struct atm_dev *) vcc->dev_data;
-	dev_data = PRIV(atmtcp_dev);
-	dev_data->vcc = NULL;
-	if (dev_data->persist) return;
-	atmtcp_dev->dev_data = NULL;
-	kfree(dev_data);
-	atm_dev_deregister(atmtcp_dev);
-	vcc->dev_data = NULL;
-	module_put(THIS_MODULE);
-}
-
-
-static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
-{
-        struct hlist_head *head;
-        struct atm_vcc *vcc;
-        struct sock *s;
-
-        head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
-
-	sk_for_each(s, head) {
-                vcc = atm_sk(s);
-                if (vcc->dev == dev &&
-                    vcc->vci == vci && vcc->vpi == vpi &&
-                    vcc->qos.rxtp.traffic_class != ATM_NONE) {
-                                return vcc;
-                }
-        }
-        return NULL;
-}
-
-static int atmtcp_c_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	struct atmtcp_hdr *hdr;
-
-	if (skb->len < sizeof(struct atmtcp_hdr))
-		return -EINVAL;
-
-	hdr = (struct atmtcp_hdr *)skb->data;
-	if (hdr->length == ATMTCP_HDR_MAGIC)
-		return -EINVAL;
-
-	return 0;
-}
-
-static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	struct atm_dev *dev;
-	struct atmtcp_hdr *hdr;
-	struct atm_vcc *out_vcc;
-	struct sk_buff *new_skb;
-	int result = 0;
-
-	dev = vcc->dev_data;
-	hdr = (struct atmtcp_hdr *) skb->data;
-	if (hdr->length == ATMTCP_HDR_MAGIC) {
-		result = atmtcp_recv_control(
-		    (struct atmtcp_control *) skb->data);
-		goto done;
-	}
-	read_lock(&vcc_sklist_lock);
-	out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
-	read_unlock(&vcc_sklist_lock);
-	if (!out_vcc) {
-		result = -EUNATCH;
-		atomic_inc(&vcc->stats->tx_err);
-		goto done;
-	}
-	skb_pull(skb,sizeof(struct atmtcp_hdr));
-	new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
-	if (!new_skb) {
-		result = -ENOBUFS;
-		goto done;
-	}
-	__net_timestamp(new_skb);
-	skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
-	out_vcc->push(out_vcc,new_skb);
-	atomic_inc(&vcc->stats->tx);
-	atomic_inc(&out_vcc->stats->rx);
-done:
-	if (vcc->pop) vcc->pop(vcc,skb);
-	else dev_kfree_skb(skb);
-	return result;
-}
-
-
-/*
- * Device operations for the virtual ATM devices created by ATMTCP.
- */
-
-
-static const struct atmdev_ops atmtcp_v_dev_ops = {
-	.dev_close	= atmtcp_v_dev_close,
-	.open		= atmtcp_v_open,
-	.close		= atmtcp_v_close,
-	.ioctl		= atmtcp_v_ioctl,
-	.send		= atmtcp_v_send,
-	.proc_read	= atmtcp_v_proc,
-	.owner		= THIS_MODULE
-};
-
-
-/*
- * Device operations for the ATMTCP control device.
- */
-
-
-static const struct atmdev_ops atmtcp_c_dev_ops = {
-	.close		= atmtcp_c_close,
-	.pre_send	= atmtcp_c_pre_send,
-	.send		= atmtcp_c_send
-};
-
-
-static struct atm_dev atmtcp_control_dev = {
-	.ops		= &atmtcp_c_dev_ops,
-	.type		= "atmtcp",
-	.number		= 999,
-	.lock		= __SPIN_LOCK_UNLOCKED(atmtcp_control_dev.lock)
-};
-
-
-static int atmtcp_create(int itf,int persist,struct atm_dev **result)
-{
-	struct atmtcp_dev_data *dev_data;
-	struct atm_dev *dev;
-
-	dev_data = kmalloc_obj(*dev_data);
-	if (!dev_data)
-		return -ENOMEM;
-
-	dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
-	if (!dev) {
-		kfree(dev_data);
-		return itf == -1 ? -ENOMEM : -EBUSY;
-	}
-	dev->ci_range.vpi_bits = MAX_VPI_BITS;
-	dev->ci_range.vci_bits = MAX_VCI_BITS;
-	dev->dev_data = dev_data;
-	PRIV(dev)->vcc = NULL;
-	PRIV(dev)->persist = persist;
-	if (result) *result = dev;
-	return 0;
-}
-
-
-static int atmtcp_attach(struct atm_vcc *vcc,int itf)
-{
-	struct atm_dev *dev;
-
-	dev = NULL;
-	if (itf != -1) dev = atm_dev_lookup(itf);
-	if (dev) {
-		if (dev->ops != &atmtcp_v_dev_ops) {
-			atm_dev_put(dev);
-			return -EMEDIUMTYPE;
-		}
-		if (PRIV(dev)->vcc) {
-			atm_dev_put(dev);
-			return -EBUSY;
-		}
-	}
-	else {
-		int error;
-
-		error = atmtcp_create(itf,0,&dev);
-		if (error) return error;
-	}
-	PRIV(dev)->vcc = vcc;
-	vcc->dev = &atmtcp_control_dev;
-	vcc_insert_socket(sk_atm(vcc));
-	set_bit(ATM_VF_META,&vcc->flags);
-	set_bit(ATM_VF_READY,&vcc->flags);
-	vcc->dev_data = dev;
-	(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
-	vcc->stats = &atmtcp_control_dev.stats.aal5;
-	return dev->number;
-}
-
-
-static int atmtcp_create_persistent(int itf)
-{
-	return atmtcp_create(itf,1,NULL);
-}
-
-
-static int atmtcp_remove_persistent(int itf)
-{
-	struct atm_dev *dev;
-	struct atmtcp_dev_data *dev_data;
-
-	dev = atm_dev_lookup(itf);
-	if (!dev) return -ENODEV;
-	if (dev->ops != &atmtcp_v_dev_ops) {
-		atm_dev_put(dev);
-		return -EMEDIUMTYPE;
-	}
-	dev_data = PRIV(dev);
-	if (!dev_data->persist) {
-		atm_dev_put(dev);
-		return 0;
-	}
-	dev_data->persist = 0;
-	if (PRIV(dev)->vcc) {
-		atm_dev_put(dev);
-		return 0;
-	}
-	kfree(dev_data);
-	atm_dev_put(dev);
-	atm_dev_deregister(dev);
-	return 0;
-}
-
-static int atmtcp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-	int err = 0;
-	struct atm_vcc *vcc = ATM_SD(sock);
-
-	if (cmd != SIOCSIFATMTCP && cmd != ATMTCP_CREATE && cmd != ATMTCP_REMOVE)
-		return -ENOIOCTLCMD;
-
-	if (!capable(CAP_NET_ADMIN))
-		return -EPERM;
-
-	switch (cmd) {
-		case SIOCSIFATMTCP:
-			err = atmtcp_attach(vcc, (int) arg);
-			if (err >= 0) {
-				sock->state = SS_CONNECTED;
-				__module_get(THIS_MODULE);
-			}
-			break;
-		case ATMTCP_CREATE:
-			err = atmtcp_create_persistent((int) arg);
-			break;
-		case ATMTCP_REMOVE:
-			err = atmtcp_remove_persistent((int) arg);
-			break;
-	}
-	return err;
-}
-
-static struct atm_ioctl atmtcp_ioctl_ops = {
-	.owner 	= THIS_MODULE,
-	.ioctl	= atmtcp_ioctl,
-};
-
-static __init int atmtcp_init(void)
-{
-	register_atm_ioctl(&atmtcp_ioctl_ops);
-	return 0;
-}
-
-
-static void __exit atmtcp_exit(void)
-{
-	deregister_atm_ioctl(&atmtcp_ioctl_ops);
-}
-
-MODULE_DESCRIPTION("ATM over TCP");
-MODULE_LICENSE("GPL");
-module_init(atmtcp_init);
-module_exit(atmtcp_exit);
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c
deleted file mode 100644
index 12cb3aa5..0000000
--- a/drivers/atm/eni.c
+++ /dev/null
@@ -1,2321 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/eni.c - Efficient Networks ENI155P device driver */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
- 
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/delay.h>
-#include <linux/uio.h>
-#include <linux/init.h>
-#include <linux/atm_eni.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include <linux/uaccess.h>
-#include <asm/string.h>
-#include <asm/byteorder.h>
-
-#include "tonga.h"
-#include "midway.h"
-#include "suni.h"
-#include "eni.h"
-
-/*
- * TODO:
- *
- * Show stoppers
- *  none
- *
- * Minor
- *  - OAM support
- *  - fix bugs listed below
- */
-
-/*
- * KNOWN BUGS:
- *
- * - may run into JK-JK bug and deadlock
- * - should allocate UBR channel first
- * - buffer space allocation algorithm is stupid
- *   (RX: should be maxSDU+maxdelay*rate
- *    TX: should be maxSDU+min(maxSDU,maxdelay*rate) )
- * - doesn't support OAM cells
- * - eni_put_free may hang if not putting memory fragments that _complete_
- *   2^n block (never happens in real life, though)
- */
-
-
-#if 0
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-
-#ifndef CONFIG_ATM_ENI_TUNE_BURST
-#define CONFIG_ATM_ENI_BURST_TX_8W
-#define CONFIG_ATM_ENI_BURST_RX_4W
-#endif
-
-
-#ifndef CONFIG_ATM_ENI_DEBUG
-
-
-#define NULLCHECK(x)
-
-#define EVENT(s,a,b)
-
-
-static void event_dump(void)
-{
-}
-
-
-#else
-
-
-/* 
- * NULL pointer checking
- */
-
-#define NULLCHECK(x) \
-	if ((unsigned long) (x) < 0x30) \
-		printk(KERN_CRIT #x "==0x%lx\n",(unsigned long) (x))
-
-/*
- * Very extensive activity logging. Greatly improves bug detection speed but
- * costs a few Mbps if enabled.
- */
-
-#define EV 64
-
-static const char *ev[EV];
-static unsigned long ev_a[EV],ev_b[EV];
-static int ec = 0;
-
-
-static void EVENT(const char *s,unsigned long a,unsigned long b)
-{
-	ev[ec] = s; 
-	ev_a[ec] = a;
-	ev_b[ec] = b;
-	ec = (ec+1) % EV;
-}
-
-
-static void event_dump(void)
-{
-	int n,i;
-
-	for (n = 0; n < EV; n++) {
-		i = (ec+n) % EV;
-		printk(KERN_NOTICE);
-		printk(ev[i] ? ev[i] : "(null)",ev_a[i],ev_b[i]);
-	}
-}
-
-
-#endif /* CONFIG_ATM_ENI_DEBUG */
-
-
-/*
- * NExx   must not be equal at end
- * EExx   may be equal at end
- * xxPJOK verify validity of pointer jumps
- * xxPMOK operating on a circular buffer of "c" words
- */
-
-#define NEPJOK(a0,a1,b) \
-    ((a0) < (a1) ? (b) <= (a0) || (b) > (a1) : (b) <= (a0) && (b) > (a1))
-#define EEPJOK(a0,a1,b) \
-    ((a0) < (a1) ? (b) < (a0) || (b) >= (a1) : (b) < (a0) && (b) >= (a1))
-#define NEPMOK(a0,d,b,c) NEPJOK(a0,(a0+d) & (c-1),b)
-#define EEPMOK(a0,d,b,c) EEPJOK(a0,(a0+d) & (c-1),b)
-
-
-static int tx_complete = 0,dma_complete = 0,queued = 0,requeued = 0,
-  backlogged = 0,rx_enqueued = 0,rx_dequeued = 0,pushed = 0,submitted = 0,
-  putting = 0;
-
-static struct atm_dev *eni_boards = NULL;
-
-/* Read/write registers on card */
-#define eni_in(r)	readl(eni_dev->reg+(r)*4)
-#define eni_out(v,r)	writel((v),eni_dev->reg+(r)*4)
-
-
-/*-------------------------------- utilities --------------------------------*/
-
-
-static void dump_mem(struct eni_dev *eni_dev)
-{
-	int i;
-
-	for (i = 0; i < eni_dev->free_len; i++)
-		printk(KERN_DEBUG "  %d: %p %d\n",i,
-		    eni_dev->free_list[i].start,
-		    1 << eni_dev->free_list[i].order);
-}
-
-
-static void dump(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-
-	int i;
-
-	eni_dev = ENI_DEV(dev);
-	printk(KERN_NOTICE "Free memory\n");
-	dump_mem(eni_dev);
-	printk(KERN_NOTICE "TX buffers\n");
-	for (i = 0; i < NR_CHAN; i++)
-		if (eni_dev->tx[i].send)
-			printk(KERN_NOTICE "  TX %d @ %p: %ld\n",i,
-			    eni_dev->tx[i].send,eni_dev->tx[i].words*4);
-	printk(KERN_NOTICE "RX buffers\n");
-	for (i = 0; i < 1024; i++)
-		if (eni_dev->rx_map[i] && ENI_VCC(eni_dev->rx_map[i])->rx)
-			printk(KERN_NOTICE "  RX %d @ %p: %ld\n",i,
-			    ENI_VCC(eni_dev->rx_map[i])->recv,
-			    ENI_VCC(eni_dev->rx_map[i])->words*4);
-	printk(KERN_NOTICE "----\n");
-}
-
-
-static void eni_put_free(struct eni_dev *eni_dev, void __iomem *start,
-    unsigned long size)
-{
-	struct eni_free *list;
-	int len,order;
-
-	DPRINTK("init 0x%lx+%ld(0x%lx)\n",start,size,size);
-	start += eni_dev->base_diff;
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	while (size) {
-		if (len >= eni_dev->free_list_size) {
-			printk(KERN_CRIT "eni_put_free overflow (%p,%ld)\n",
-			    start,size);
-			break;
-		}
-		for (order = 0; !(((unsigned long)start | size) & (1 << order)); order++);
-		if (MID_MIN_BUF_SIZE > (1 << order)) {
-			printk(KERN_CRIT "eni_put_free: order %d too small\n",
-			    order);
-			break;
-		}
-		list[len].start = (void __iomem *) start;
-		list[len].order = order;
-		len++;
-		start += 1 << order;
-		size -= 1 << order;
-	}
-	eni_dev->free_len = len;
-	/*dump_mem(eni_dev);*/
-}
-
-
-static void __iomem *eni_alloc_mem(struct eni_dev *eni_dev, unsigned long *size)
-{
-	struct eni_free *list;
-	void __iomem *start;
-	int len,i,order,best_order,index;
-
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	if (*size < MID_MIN_BUF_SIZE) *size = MID_MIN_BUF_SIZE;
-	if (*size > MID_MAX_BUF_SIZE) return NULL;
-	for (order = 0; (1 << order) < *size; order++)
-		;
-	DPRINTK("trying: %ld->%d\n",*size,order);
-	best_order = 65; /* we don't have more than 2^64 of anything ... */
-	index = 0; /* silence GCC */
-	for (i = 0; i < len; i++)
-		if (list[i].order == order) {
-			best_order = order;
-			index = i;
-			break;
-		}
-		else if (best_order > list[i].order && list[i].order > order) {
-				best_order = list[i].order;
-				index = i;
-			}
-	if (best_order == 65) return NULL;
-	start = list[index].start-eni_dev->base_diff;
-	list[index] = list[--len];
-	eni_dev->free_len = len;
-	*size = 1 << order;
-	eni_put_free(eni_dev,start+*size,(1 << best_order)-*size);
-	DPRINTK("%ld bytes (order %d) at 0x%lx\n",*size,order,start);
-	memset_io(start,0,*size);       /* never leak data */
-	/*dump_mem(eni_dev);*/
-	return start;
-}
-
-
-static void eni_free_mem(struct eni_dev *eni_dev, void __iomem *start,
-    unsigned long size)
-{
-	struct eni_free *list;
-	int len,i,order;
-
-	start += eni_dev->base_diff;
-	list = eni_dev->free_list;
-	len = eni_dev->free_len;
-	for (order = -1; size; order++) size >>= 1;
-	DPRINTK("eni_free_mem: %p+0x%lx (order %d)\n",start,size,order);
-	for (i = 0; i < len; i++)
-		if (((unsigned long) list[i].start) == ((unsigned long)start^(1 << order)) &&
-		    list[i].order == order) {
-			DPRINTK("match[%d]: 0x%lx/0x%lx(0x%x), %d/%d\n",i,
-			    list[i].start,start,1 << order,list[i].order,order);
-			list[i] = list[--len];
-			start = (void __iomem *) ((unsigned long) start & ~(unsigned long) (1 << order));
-			order++;
-			i = -1;
-			continue;
-		}
-	if (len >= eni_dev->free_list_size) {
-		printk(KERN_ALERT "eni_free_mem overflow (%p,%d)\n",start,
-		    order);
-		return;
-	}
-	list[len].start = start;
-	list[len].order = order;
-	eni_dev->free_len = len+1;
-	/*dump_mem(eni_dev);*/
-}
-
-
-/*----------------------------------- RX ------------------------------------*/
-
-
-#define ENI_VCC_NOS ((struct atm_vcc *) 1)
-
-
-static void rx_ident_err(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	dev = vcc->dev;
-	eni_dev = ENI_DEV(dev);
-	/* immediately halt adapter */
-	eni_out(eni_in(MID_MC_S) &
-	    ~(MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE),MID_MC_S);
-	/* dump useful information */
-	eni_vcc = ENI_VCC(vcc);
-	printk(KERN_ALERT DEV_LABEL "(itf %d): driver error - RX ident "
-	    "mismatch\n",dev->number);
-	printk(KERN_ALERT "  VCI %d, rxing %d, words %ld\n",vcc->vci,
-	    eni_vcc->rxing,eni_vcc->words);
-	printk(KERN_ALERT "  host descr 0x%lx, rx pos 0x%lx, descr value "
-	    "0x%x\n",eni_vcc->descr,eni_vcc->rx_pos,
-	    (unsigned) readl(eni_vcc->recv+eni_vcc->descr*4));
-	printk(KERN_ALERT "  last %p, servicing %d\n",eni_vcc->last,
-	    eni_vcc->servicing);
-	EVENT("---dump ends here---\n",0,0);
-	printk(KERN_NOTICE "---recent events---\n");
-	event_dump();
-	ENI_DEV(dev)->fast = NULL; /* really stop it */
-	ENI_DEV(dev)->slow = NULL;
-	skb_queue_head_init(&ENI_DEV(dev)->rx_queue);
-}
-
-
-static int do_rx_dma(struct atm_vcc *vcc,struct sk_buff *skb,
-    unsigned long skip,unsigned long size,unsigned long eff)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	u32 dma_rd,dma_wr;
-	u32 dma[RX_DMA_BUF*2];
-	dma_addr_t paddr;
-	unsigned long here;
-	int i,j;
-
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	paddr = 0; /* GCC, shut up */
-	if (skb) {
-		paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
-				       DMA_FROM_DEVICE);
-		if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
-			goto dma_map_error;
-		ENI_PRV_PADDR(skb) = paddr;
-		if (paddr & 3)
-			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d has "
-			    "mis-aligned RX data (0x%lx)\n",vcc->dev->number,
-			    vcc->vci,(unsigned long) paddr);
-		ENI_PRV_SIZE(skb) = size+skip;
-		    /* PDU plus descriptor */
-		ATM_SKB(skb)->vcc = vcc;
-	}
-	j = 0;
-	if ((eff && skip) || 1) { /* @@@ actually, skip is always == 1 ... */
-		here = (eni_vcc->descr+skip) & (eni_vcc->words-1);
-		dma[j++] = (here << MID_DMA_COUNT_SHIFT) | (vcc->vci
-		    << MID_DMA_VCI_SHIFT) | MID_DT_JK;
-		dma[j++] = 0;
-	}
-	here = (eni_vcc->descr+size+skip) & (eni_vcc->words-1);
-	if (!eff) size += skip;
-	else {
-		unsigned long words;
-
-		if (!size) {
-			DPRINTK("strange things happen ...\n");
-			EVENT("strange things happen ... (skip=%ld,eff=%ld)\n",
-			    size,eff);
-		}
-		words = eff;
-		if (paddr & 15) {
-			unsigned long init;
-
-			init = 4-((paddr & 15) >> 2);
-			if (init > words) init = words;
-			dma[j++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
-			    (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += init << 2;
-			words -= init;
-		}
-#ifdef CONFIG_ATM_ENI_BURST_RX_16W /* may work with some PCI chipsets ... */
-		if (words & ~15) {
-			dma[j++] = MID_DT_16W | ((words >> 4) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~15) << 2;
-			words &= 15;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_8W  /* works only with *some* PCI chipsets ... */
-		if (words & ~7) {
-			dma[j++] = MID_DT_8W | ((words >> 3) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~7) << 2;
-			words &= 7;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_4W /* recommended */
-		if (words & ~3) {
-			dma[j++] = MID_DT_4W | ((words >> 2) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~3) << 2;
-			words &= 3;
-		}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_2W /* probably useless if RX_4W, RX_8W, ... */
-		if (words & ~1) {
-			dma[j++] = MID_DT_2W | ((words >> 1) <<
-			    MID_DMA_COUNT_SHIFT) | (vcc->vci <<
-			    MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-			paddr += (words & ~1) << 2;
-			words &= 1;
-		}
-#endif
-		if (words) {
-			dma[j++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT)
-			    | (vcc->vci << MID_DMA_VCI_SHIFT);
-			dma[j++] = paddr;
-		}
-	}
-	if (size != eff) {
-		dma[j++] = (here << MID_DMA_COUNT_SHIFT) |
-		    (vcc->vci << MID_DMA_VCI_SHIFT) | MID_DT_JK;
-		dma[j++] = 0;
-	}
-	if (!j || j > 2*RX_DMA_BUF) {
-		printk(KERN_CRIT DEV_LABEL "!j or j too big!!!\n");
-		goto trouble;
-	}
-	dma[j-2] |= MID_DMA_END;
-	j = j >> 1;
-	dma_wr = eni_in(MID_DMA_WR_RX);
-	dma_rd = eni_in(MID_DMA_RD_RX);
-	/*
-	 * Can I move the dma_wr pointer by 2j+1 positions without overwriting
-	 * data that hasn't been read (position of dma_rd) yet ?
-	 */
-	if (!NEPMOK(dma_wr,j+j+1,dma_rd,NR_DMA_RX)) { /* @@@ +1 is ugly */
-		printk(KERN_WARNING DEV_LABEL "(itf %d): RX DMA full\n",
-		    vcc->dev->number);
-		goto trouble;
-	}
-        for (i = 0; i < j; i++) {
-		writel(dma[i*2],eni_dev->rx_dma+dma_wr*8);
-		writel(dma[i*2+1],eni_dev->rx_dma+dma_wr*8+4);
-		dma_wr = (dma_wr+1) & (NR_DMA_RX-1);
-        }
-	if (skb) {
-		ENI_PRV_POS(skb) = eni_vcc->descr+size+1;
-		skb_queue_tail(&eni_dev->rx_queue,skb);
-		eni_vcc->last = skb;
-		rx_enqueued++;
-	}
-	eni_vcc->descr = here;
-	eni_out(dma_wr,MID_DMA_WR_RX);
-	return 0;
-
-trouble:
-	if (paddr)
-		dma_unmap_single(&eni_dev->pci_dev->dev,paddr,skb->len,
-				 DMA_FROM_DEVICE);
-dma_map_error:
-	if (skb) dev_kfree_skb_irq(skb);
-	return -1;
-}
-
-
-static void discard(struct atm_vcc *vcc,unsigned long size)
-{
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	EVENT("discard (size=%ld)\n",size,0);
-	while (do_rx_dma(vcc,NULL,1,size,0)) EVENT("BUSY LOOP",0,0);
-	    /* could do a full fallback, but that might be more expensive */
-	if (eni_vcc->rxing) ENI_PRV_POS(eni_vcc->last) += size+1;
-	else eni_vcc->rx_pos = (eni_vcc->rx_pos+size+1) & (eni_vcc->words-1);
-}
-
-
-/*
- * TODO: should check whether direct copies (without DMA setup, dequeuing on
- * interrupt, etc.) aren't much faster for AAL0
- */
-
-static int rx_aal0(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	unsigned long descr;
-	unsigned long length;
-	struct sk_buff *skb;
-
-	DPRINTK(">rx_aal0\n");
-	eni_vcc = ENI_VCC(vcc);
-	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
-	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
-		rx_ident_err(vcc);
-		return 1;
-	}
-	if (descr & MID_RED_T) {
-		DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
-		    vcc->dev->number);
-		length = 0;
-		atomic_inc(&vcc->stats->rx_err);
-	}
-	else {
-		length = ATM_CELL_SIZE-1; /* no HEC */
-	}
-	skb = length ? atm_alloc_charge(vcc,length,GFP_ATOMIC) : NULL;
-	if (!skb) {
-		discard(vcc,length >> 2);
-		return 0;
-	}
-	skb_put(skb,length);
-	skb->tstamp = eni_vcc->timestamp;
-	DPRINTK("got len %ld\n",length);
-	if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
-	eni_vcc->rxing++;
-	return 0;
-}
-
-
-static int rx_aal5(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	unsigned long descr;
-	unsigned long size,eff,length;
-	struct sk_buff *skb;
-
-	EVENT("rx_aal5\n",0,0);
-	DPRINTK(">rx_aal5\n");
-	eni_vcc = ENI_VCC(vcc);
-	descr = readl(eni_vcc->recv+eni_vcc->descr*4);
-	if ((descr & MID_RED_IDEN) != (MID_RED_RX_ID << MID_RED_SHIFT)) {
-		rx_ident_err(vcc);
-		return 1;
-	}
-	if (descr & (MID_RED_T | MID_RED_CRC_ERR)) {
-		if (descr & MID_RED_T) {
-			EVENT("empty cell (descr=0x%lx)\n",descr,0);
-			DPRINTK(DEV_LABEL "(itf %d): trashing empty cell\n",
-			    vcc->dev->number);
-			size = 0;
-		}
-		else {
-			static unsigned long silence = 0;
-
-			if (time_after(jiffies, silence) || silence == 0) {
-				printk(KERN_WARNING DEV_LABEL "(itf %d): "
-				    "discarding PDU(s) with CRC error\n",
-				    vcc->dev->number);
-				silence = (jiffies+2*HZ)|1;
-			}
-			size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
-			EVENT("CRC error (descr=0x%lx,size=%ld)\n",descr,
-			    size);
-		}
-		eff = length = 0;
-		atomic_inc(&vcc->stats->rx_err);
-	}
-	else {
-		size = (descr & MID_RED_COUNT)*(ATM_CELL_PAYLOAD >> 2);
-		DPRINTK("size=%ld\n",size);
-		length = readl(eni_vcc->recv+(((eni_vcc->descr+size-1) &
-		    (eni_vcc->words-1)))*4) & 0xffff;
-				/* -trailer(2)+header(1) */
-		if (length && length <= (size << 2)-8 && length <=
-		  ATM_MAX_AAL5_PDU) eff = (length+3) >> 2;
-		else {				 /* ^ trailer length (8) */
-			EVENT("bad PDU (descr=0x08%lx,length=%ld)\n",descr,
-			    length);
-			printk(KERN_ERR DEV_LABEL "(itf %d): bad AAL5 PDU "
-			    "(VCI=%d,length=%ld,size=%ld (descr 0x%lx))\n",
-			    vcc->dev->number,vcc->vci,length,size << 2,descr);
-			length = eff = 0;
-			atomic_inc(&vcc->stats->rx_err);
-		}
-	}
-	skb = eff ? atm_alloc_charge(vcc,eff << 2,GFP_ATOMIC) : NULL;
-	if (!skb) {
-		discard(vcc,size);
-		return 0;
-	}
-	skb_put(skb,length);
-	DPRINTK("got len %ld\n",length);
-	if (do_rx_dma(vcc,skb,1,size,eff)) return 1;
-	eni_vcc->rxing++;
-	return 0;
-}
-
-
-static inline int rx_vcc(struct atm_vcc *vcc)
-{
-	void __iomem *vci_dsc;
-	unsigned long tmp;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	vci_dsc = ENI_DEV(vcc->dev)->vci+vcc->vci*16;
-	EVENT("rx_vcc(1)\n",0,0);
-	while (eni_vcc->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR) >>
-	    MID_VCI_DESCR_SHIFT)) {
-		EVENT("rx_vcc(2: host dsc=0x%lx, nic dsc=0x%lx)\n",
-		    eni_vcc->descr,tmp);
-		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
-		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
-		    MID_VCI_DESCR_SHIFT));
-		if (ENI_VCC(vcc)->rx(vcc)) return 1;
-	}
-	/* clear IN_SERVICE flag */
-	writel(readl(vci_dsc) & ~MID_VCI_IN_SERVICE,vci_dsc);
-	/*
-	 * If new data has arrived between evaluating the while condition and
-	 * clearing IN_SERVICE, we wouldn't be notified until additional data
-	 * follows. So we have to loop again to be sure.
-	 */
-	EVENT("rx_vcc(3)\n",0,0);
-	while (ENI_VCC(vcc)->descr != (tmp = (readl(vci_dsc+4) & MID_VCI_DESCR)
-	    >> MID_VCI_DESCR_SHIFT)) {
-		EVENT("rx_vcc(4: host dsc=0x%lx, nic dsc=0x%lx)\n",
-		    eni_vcc->descr,tmp);
-		DPRINTK("CB_DESCR %ld REG_DESCR %d\n",ENI_VCC(vcc)->descr,
-		    (((unsigned) readl(vci_dsc+4) & MID_VCI_DESCR) >>
-		    MID_VCI_DESCR_SHIFT));
-		if (ENI_VCC(vcc)->rx(vcc)) return 1;
-	}
-	return 0;
-}
-
-
-static void poll_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *curr;
-
-	eni_dev = ENI_DEV(dev);
-	while ((curr = eni_dev->fast)) {
-		EVENT("poll_rx.fast\n",0,0);
-		if (rx_vcc(curr)) return;
-		eni_dev->fast = ENI_VCC(curr)->next;
-		ENI_VCC(curr)->next = ENI_VCC_NOS;
-		barrier();
-		ENI_VCC(curr)->servicing--;
-	}
-	while ((curr = eni_dev->slow)) {
-		EVENT("poll_rx.slow\n",0,0);
-		if (rx_vcc(curr)) return;
-		eni_dev->slow = ENI_VCC(curr)->next;
-		ENI_VCC(curr)->next = ENI_VCC_NOS;
-		barrier();
-		ENI_VCC(curr)->servicing--;
-	}
-}
-
-
-static void get_service(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *vcc;
-	unsigned long vci;
-
-	DPRINTK(">get_service\n");
-	eni_dev = ENI_DEV(dev);
-	while (eni_in(MID_SERV_WRITE) != eni_dev->serv_read) {
-		vci = readl(eni_dev->service+eni_dev->serv_read*4);
-		eni_dev->serv_read = (eni_dev->serv_read+1) & (NR_SERVICE-1);
-		vcc = eni_dev->rx_map[vci & 1023];
-		if (!vcc) {
-			printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %ld not "
-			    "found\n",dev->number,vci);
-			continue; /* nasty but we try to go on anyway */
-			/* @@@ nope, doesn't work */
-		}
-		EVENT("getting from service\n",0,0);
-		if (ENI_VCC(vcc)->next != ENI_VCC_NOS) {
-			EVENT("double service\n",0,0);
-			DPRINTK("Grr, servicing VCC %ld twice\n",vci);
-			continue;
-		}
-		ENI_VCC(vcc)->timestamp = ktime_get_real();
-		ENI_VCC(vcc)->next = NULL;
-		if (vcc->qos.rxtp.traffic_class == ATM_CBR) {
-			if (eni_dev->fast)
-				ENI_VCC(eni_dev->last_fast)->next = vcc;
-			else eni_dev->fast = vcc;
-			eni_dev->last_fast = vcc;
-		}
-		else {
-			if (eni_dev->slow)
-				ENI_VCC(eni_dev->last_slow)->next = vcc;
-			else eni_dev->slow = vcc;
-			eni_dev->last_slow = vcc;
-		}
-		putting++;
-		ENI_VCC(vcc)->servicing++;
-	}
-}
-
-
-static void dequeue_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	void __iomem *vci_dsc;
-	int first;
-
-	eni_dev = ENI_DEV(dev);
-	first = 1;
-	while (1) {
-		skb = skb_dequeue(&eni_dev->rx_queue);
-		if (!skb) {
-			if (first) {
-				DPRINTK(DEV_LABEL "(itf %d): RX but not "
-				    "rxing\n",dev->number);
-				EVENT("nothing to dequeue\n",0,0);
-			}
-			break;
-		}
-		EVENT("dequeued (size=%ld,pos=0x%lx)\n",ENI_PRV_SIZE(skb),
-		    ENI_PRV_POS(skb));
-		rx_dequeued++;
-		vcc = ATM_SKB(skb)->vcc;
-		eni_vcc = ENI_VCC(vcc);
-		first = 0;
-		vci_dsc = eni_dev->vci+vcc->vci*16;
-		if (!EEPMOK(eni_vcc->rx_pos,ENI_PRV_SIZE(skb),
-		    (readl(vci_dsc+4) & MID_VCI_READ) >> MID_VCI_READ_SHIFT,
-		    eni_vcc->words)) {
-			EVENT("requeuing\n",0,0);
-			skb_queue_head(&eni_dev->rx_queue,skb);
-			break;
-		}
-		eni_vcc->rxing--;
-		eni_vcc->rx_pos = ENI_PRV_POS(skb) & (eni_vcc->words-1);
-		dma_unmap_single(&eni_dev->pci_dev->dev,ENI_PRV_PADDR(skb),skb->len,
-			         DMA_TO_DEVICE);
-		if (!skb->len) dev_kfree_skb_irq(skb);
-		else {
-			EVENT("pushing (len=%ld)\n",skb->len,0);
-			if (vcc->qos.aal == ATM_AAL0)
-				*(unsigned long *) skb->data =
-				    ntohl(*(unsigned long *) skb->data);
-			memset(skb->cb,0,sizeof(struct eni_skb_prv));
-			vcc->push(vcc,skb);
-			pushed++;
-		}
-		atomic_inc(&vcc->stats->rx);
-	}
-	wake_up(&eni_dev->rx_wait);
-}
-
-
-static int open_rx_first(struct atm_vcc *vcc)
-{
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	unsigned long size;
-
-	DPRINTK("open_rx_first\n");
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	eni_vcc->rx = NULL;
-	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;
-	size = vcc->qos.rxtp.max_sdu*eni_dev->rx_mult/100;
-	if (size > MID_MAX_BUF_SIZE && vcc->qos.rxtp.max_sdu <=
-	    MID_MAX_BUF_SIZE)
-		size = MID_MAX_BUF_SIZE;
-	eni_vcc->recv = eni_alloc_mem(eni_dev,&size);
-	DPRINTK("rx at 0x%lx\n",eni_vcc->recv);
-	eni_vcc->words = size >> 2;
-	if (!eni_vcc->recv) return -ENOBUFS;
-	eni_vcc->rx = vcc->qos.aal == ATM_AAL5 ? rx_aal5 : rx_aal0;
-	eni_vcc->descr = 0;
-	eni_vcc->rx_pos = 0;
-	eni_vcc->rxing = 0;
-	eni_vcc->servicing = 0;
-	eni_vcc->next = ENI_VCC_NOS;
-	return 0;
-}
-
-
-static int open_rx_second(struct atm_vcc *vcc)
-{
-	void __iomem *here;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	unsigned long size;
-	int order;
-
-	DPRINTK("open_rx_second\n");
-	eni_dev = ENI_DEV(vcc->dev);
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->rx) return 0;
-	/* set up VCI descriptor */
-	here = eni_dev->vci+vcc->vci*16;
-	DPRINTK("loc 0x%x\n",(unsigned) (eni_vcc->recv-eni_dev->ram)/4);
-	size = eni_vcc->words >> 8;
-	for (order = -1; size; order++) size >>= 1;
-	writel(0,here+4); /* descr, read = 0 */
-	writel(0,here+8); /* write, state, count = 0 */
-	if (eni_dev->rx_map[vcc->vci])
-		printk(KERN_CRIT DEV_LABEL "(itf %d): BUG - VCI %d already "
-		    "in use\n",vcc->dev->number,vcc->vci);
-	eni_dev->rx_map[vcc->vci] = vcc; /* now it counts */
-	writel(((vcc->qos.aal != ATM_AAL5 ? MID_MODE_RAW : MID_MODE_AAL5) <<
-	    MID_VCI_MODE_SHIFT) | MID_VCI_PTI_MODE |
-	    (((eni_vcc->recv-eni_dev->ram) >> (MID_LOC_SKIP+2)) <<
-	    MID_VCI_LOCATION_SHIFT) | (order << MID_VCI_SIZE_SHIFT),here);
-	return 0;
-}
-
-
-static void close_rx(struct atm_vcc *vcc)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	void __iomem *here;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->rx) return;
-	eni_dev = ENI_DEV(vcc->dev);
-	if (vcc->vpi != ATM_VPI_UNSPEC && vcc->vci != ATM_VCI_UNSPEC) {
-		here = eni_dev->vci+vcc->vci*16;
-		/* block receiver */
-		writel((readl(here) & ~MID_VCI_MODE) | (MID_MODE_TRASH <<
-		    MID_VCI_MODE_SHIFT),here);
-		/* wait for receiver to become idle */
-		udelay(27);
-		/* discard pending cell */
-		writel(readl(here) & ~MID_VCI_IN_SERVICE,here);
-		/* don't accept any new ones */
-		eni_dev->rx_map[vcc->vci] = NULL;
-		/* wait for RX queue to drain */
-		DPRINTK("eni_close: waiting for RX ...\n");
-		EVENT("RX closing\n",0,0);
-		add_wait_queue(&eni_dev->rx_wait,&wait);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		barrier();
-		for (;;) {
-			/* transition service->rx: rxing++, servicing-- */
-			if (!eni_vcc->servicing) {
-				barrier();
-				if (!eni_vcc->rxing) break;
-			}
-			EVENT("drain PDUs (rx %ld, serv %ld)\n",eni_vcc->rxing,
-			    eni_vcc->servicing);
-			printk(KERN_INFO "%d+%d RX left\n",eni_vcc->servicing,
-			    eni_vcc->rxing);
-			schedule();
-			set_current_state(TASK_UNINTERRUPTIBLE);
-		}
-		for (;;) {
-			int at_end;
-			u32 tmp;
-
-			tasklet_disable(&eni_dev->task);
-			tmp = readl(eni_dev->vci+vcc->vci*16+4) & MID_VCI_READ;
-			at_end = eni_vcc->rx_pos == tmp >> MID_VCI_READ_SHIFT;
-			tasklet_enable(&eni_dev->task);
-			if (at_end) break;
-			EVENT("drain discard (host 0x%lx, nic 0x%lx)\n",
-			    eni_vcc->rx_pos,tmp);
-			printk(KERN_INFO "draining RX: host 0x%lx, nic 0x%x\n",
-			    eni_vcc->rx_pos,tmp);
-			schedule();
-			set_current_state(TASK_UNINTERRUPTIBLE);
-		}
-		set_current_state(TASK_RUNNING);
-		remove_wait_queue(&eni_dev->rx_wait,&wait);
-	}
-	eni_free_mem(eni_dev,eni_vcc->recv,eni_vcc->words << 2);
-	eni_vcc->rx = NULL;
-}
-
-
-static int start_rx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-
-	eni_dev = ENI_DEV(dev);
-	eni_dev->rx_map = (struct atm_vcc **) get_zeroed_page(GFP_KERNEL);
-	if (!eni_dev->rx_map) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
-		    dev->number);
-		free_page((unsigned long) eni_dev->free_list);
-		return -ENOMEM;
-	}
-	eni_dev->rx_mult = DEFAULT_RX_MULT;
-	eni_dev->fast = eni_dev->last_fast = NULL;
-	eni_dev->slow = eni_dev->last_slow = NULL;
-	init_waitqueue_head(&eni_dev->rx_wait);
-	skb_queue_head_init(&eni_dev->rx_queue);
-	eni_dev->serv_read = eni_in(MID_SERV_WRITE);
-	eni_out(0,MID_DMA_WR_RX);
-	return 0;
-}
-
-
-/*----------------------------------- TX ------------------------------------*/
-
-
-enum enq_res { enq_ok,enq_next,enq_jam };
-
-
-static inline void put_dma(int chan,u32 *dma,int *j,dma_addr_t paddr,
-    u32 size)
-{
-	u32 init,words;
-
-	DPRINTK("put_dma: 0x%lx+0x%x\n",(unsigned long) paddr,size);
-	EVENT("put_dma: 0x%lx+0x%lx\n",(unsigned long) paddr,size);
-#if 0 /* don't complain anymore */
-	if (paddr & 3)
-		printk(KERN_ERR "put_dma: unaligned addr (0x%lx)\n",paddr);
-	if (size & 3)
-		printk(KERN_ERR "put_dma: unaligned size (0x%lx)\n",size);
-#endif
-	if (paddr & 3) {
-		init = 4-(paddr & 3);
-		if (init > size || size < 7) init = size;
-		DPRINTK("put_dma: %lx DMA: %d/%d bytes\n",
-		    (unsigned long) paddr,init,size);
-		dma[(*j)++] = MID_DT_BYTE | (init << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += init;
-		size -= init;
-	}
-	words = size >> 2;
-	size &= 3;
-	if (words && (paddr & 31)) {
-		init = 8-((paddr & 31) >> 2);
-		if (init > words) init = words;
-		DPRINTK("put_dma: %lx DMA: %d/%d words\n",
-		    (unsigned long) paddr,init,words);
-		dma[(*j)++] = MID_DT_WORD | (init << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += init << 2;
-		words -= init;
-	}
-#ifdef CONFIG_ATM_ENI_BURST_TX_16W /* may work with some PCI chipsets ... */
-	if (words & ~15) {
-		DPRINTK("put_dma: %lx DMA: %d*16/%d words\n",
-		    (unsigned long) paddr,words >> 4,words);
-		dma[(*j)++] = MID_DT_16W | ((words >> 4) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~15) << 2;
-		words &= 15;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_8W /* recommended */
-	if (words & ~7) {
-		DPRINTK("put_dma: %lx DMA: %d*8/%d words\n",
-		    (unsigned long) paddr,words >> 3,words);
-		dma[(*j)++] = MID_DT_8W | ((words >> 3) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~7) << 2;
-		words &= 7;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_4W /* probably useless if TX_8W or TX_16W */
-	if (words & ~3) {
-		DPRINTK("put_dma: %lx DMA: %d*4/%d words\n",
-		    (unsigned long) paddr,words >> 2,words);
-		dma[(*j)++] = MID_DT_4W | ((words >> 2) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~3) << 2;
-		words &= 3;
-	}
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_2W /* probably useless if TX_4W, TX_8W, ... */
-	if (words & ~1) {
-		DPRINTK("put_dma: %lx DMA: %d*2/%d words\n",
-		    (unsigned long) paddr,words >> 1,words);
-		dma[(*j)++] = MID_DT_2W | ((words >> 1) << MID_DMA_COUNT_SHIFT)
-		    | (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += (words & ~1) << 2;
-		words &= 1;
-	}
-#endif
-	if (words) {
-		DPRINTK("put_dma: %lx DMA: %d words\n",(unsigned long) paddr,
-		    words);
-		dma[(*j)++] = MID_DT_WORD | (words << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-		paddr += words << 2;
-	}
-	if (size) {
-		DPRINTK("put_dma: %lx DMA: %d bytes\n",(unsigned long) paddr,
-		    size);
-		dma[(*j)++] = MID_DT_BYTE | (size << MID_DMA_COUNT_SHIFT) |
-		    (chan << MID_DMA_CHAN_SHIFT);
-		dma[(*j)++] = paddr;
-	}
-}
-
-
-static enum enq_res do_tx(struct sk_buff *skb)
-{
-	struct atm_vcc *vcc;
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-	struct eni_tx *tx;
-	dma_addr_t paddr;
-	u32 dma_rd,dma_wr;
-	u32 size; /* in words */
-	int aal5,dma_size,i,j;
-	unsigned char skb_data3;
-
-	DPRINTK(">do_tx\n");
-	NULLCHECK(skb);
-	EVENT("do_tx: skb=0x%lx, %ld bytes\n",(unsigned long) skb,skb->len);
-	vcc = ATM_SKB(skb)->vcc;
-	NULLCHECK(vcc);
-	eni_dev = ENI_DEV(vcc->dev);
-	NULLCHECK(eni_dev);
-	eni_vcc = ENI_VCC(vcc);
-	tx = eni_vcc->tx;
-	NULLCHECK(tx);
-#if 0 /* Enable this for testing with the "align" program */
-	{
-		unsigned int hack = *((char *) skb->data)-'0';
-
-		if (hack < 8) {
-			skb->data += hack;
-			skb->len -= hack;
-		}
-	}
-#endif
-#if 0 /* should work now */
-	if ((unsigned long) skb->data & 3)
-		printk(KERN_ERR DEV_LABEL "(itf %d): VCI %d has mis-aligned "
-		    "TX data\n",vcc->dev->number,vcc->vci);
-#endif
-	/*
-	 * Potential future IP speedup: make hard_header big enough to put
-	 * segmentation descriptor directly into PDU. Saves: 4 slave writes,
-	 * 1 DMA xfer & 2 DMA'ed bytes (protocol layering is for wimps :-)
-	 */
-
-	aal5 = vcc->qos.aal == ATM_AAL5;
-	/* check space in buffer */
-	if (!aal5)
-		size = (ATM_CELL_PAYLOAD >> 2)+TX_DESCR_SIZE;
-			/* cell without HEC plus segmentation header (includes
-			   four-byte cell header) */
-	else {
-		size = skb->len+4*AAL5_TRAILER+ATM_CELL_PAYLOAD-1;
-			/* add AAL5 trailer */
-		size = ((size-(size % ATM_CELL_PAYLOAD)) >> 2)+TX_DESCR_SIZE;
-						/* add segmentation header */
-	}
-	/*
-	 * Can I move tx_pos by size bytes without getting closer than TX_GAP
-	 * to the read pointer ? TX_GAP means to leave some space for what
-	 * the manual calls "too close".
-	 */
-	if (!NEPMOK(tx->tx_pos,size+TX_GAP,
-	    eni_in(MID_TX_RDPTR(tx->index)),tx->words)) {
-		DPRINTK(DEV_LABEL "(itf %d): TX full (size %d)\n",
-		    vcc->dev->number,size);
-		return enq_next;
-	}
-	/* check DMA */
-	dma_wr = eni_in(MID_DMA_WR_TX);
-	dma_rd = eni_in(MID_DMA_RD_TX);
-	dma_size = 3; /* JK for descriptor and final fill, plus final size
-			 mis-alignment fix */
-DPRINTK("iovcnt = %d\n",skb_shinfo(skb)->nr_frags);
-	if (!skb_shinfo(skb)->nr_frags) dma_size += 5;
-	else dma_size += 5*(skb_shinfo(skb)->nr_frags+1);
-	if (dma_size > TX_DMA_BUF) {
-		printk(KERN_CRIT DEV_LABEL "(itf %d): needs %d DMA entries "
-		    "(got only %d)\n",vcc->dev->number,dma_size,TX_DMA_BUF);
-	}
-	DPRINTK("dma_wr is %d, tx_pos is %ld\n",dma_wr,tx->tx_pos);
-	if (dma_wr != dma_rd && ((dma_rd+NR_DMA_TX-dma_wr) & (NR_DMA_TX-1)) <
-	     dma_size) {
-		printk(KERN_WARNING DEV_LABEL "(itf %d): TX DMA full\n",
-		    vcc->dev->number);
-		return enq_jam;
-	}
-	skb_data3 = skb->data[3];
-	paddr = dma_map_single(&eni_dev->pci_dev->dev,skb->data,skb->len,
-			       DMA_TO_DEVICE);
-	if (dma_mapping_error(&eni_dev->pci_dev->dev, paddr))
-		return enq_next;
-	ENI_PRV_PADDR(skb) = paddr;
-	/* prepare DMA queue entries */
-	j = 0;
-	eni_dev->dma[j++] = (((tx->tx_pos+TX_DESCR_SIZE) & (tx->words-1)) <<
-	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
-	     MID_DT_JK;
-	j++;
-	if (!skb_shinfo(skb)->nr_frags)
-		if (aal5) put_dma(tx->index,eni_dev->dma,&j,paddr,skb->len);
-		else put_dma(tx->index,eni_dev->dma,&j,paddr+4,skb->len-4);
-	else {
-DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
-		for (i = -1; i < skb_shinfo(skb)->nr_frags; i++)
-			if (i == -1)
-				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-				    skb->data,
-				    skb_headlen(skb));
-			else
-				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-				    skb_frag_page(&skb_shinfo(skb)->frags[i]) +
-					skb_frag_off(&skb_shinfo(skb)->frags[i]),
-				    skb_frag_size(&skb_shinfo(skb)->frags[i]));
-	}
-	if (skb->len & 3) {
-		put_dma(tx->index, eni_dev->dma, &j, eni_dev->zero.dma,
-			4 - (skb->len & 3));
-	}
-	/* JK for AAL5 trailer - AAL0 doesn't need it, but who cares ... */
-	eni_dev->dma[j++] = (((tx->tx_pos+size) & (tx->words-1)) <<
-	     MID_DMA_COUNT_SHIFT) | (tx->index << MID_DMA_CHAN_SHIFT) |
-	     MID_DMA_END | MID_DT_JK;
-	j++;
-	DPRINTK("DMA at end: %d\n",j);
-	/* store frame */
-	writel((MID_SEG_TX_ID << MID_SEG_ID_SHIFT) |
-	    (aal5 ? MID_SEG_AAL5 : 0) | (tx->prescaler << MID_SEG_PR_SHIFT) |
-	    (tx->resolution << MID_SEG_RATE_SHIFT) |
-	    (size/(ATM_CELL_PAYLOAD/4)),tx->send+tx->tx_pos*4);
-/*printk("dsc = 0x%08lx\n",(unsigned long) readl(tx->send+tx->tx_pos*4));*/
-	writel((vcc->vci << MID_SEG_VCI_SHIFT) |
-            (aal5 ? 0 : (skb_data3 & 0xf)) |
-	    (ATM_SKB(skb)->atm_options & ATM_ATMOPT_CLP ? MID_SEG_CLP : 0),
-	    tx->send+((tx->tx_pos+1) & (tx->words-1))*4);
-	DPRINTK("size: %d, len:%d\n",size,skb->len);
-	if (aal5)
-		writel(skb->len,tx->send+
-                    ((tx->tx_pos+size-AAL5_TRAILER) & (tx->words-1))*4);
-	j = j >> 1;
-	for (i = 0; i < j; i++) {
-		writel(eni_dev->dma[i*2],eni_dev->tx_dma+dma_wr*8);
-		writel(eni_dev->dma[i*2+1],eni_dev->tx_dma+dma_wr*8+4);
-		dma_wr = (dma_wr+1) & (NR_DMA_TX-1);
-	}
-	ENI_PRV_POS(skb) = tx->tx_pos;
-	ENI_PRV_SIZE(skb) = size;
-	ENI_VCC(vcc)->txing += size;
-	tx->tx_pos = (tx->tx_pos+size) & (tx->words-1);
-	DPRINTK("dma_wr set to %d, tx_pos is now %ld\n",dma_wr,tx->tx_pos);
-	eni_out(dma_wr,MID_DMA_WR_TX);
-	skb_queue_tail(&eni_dev->tx_queue,skb);
-	queued++;
-	return enq_ok;
-}
-
-
-static void poll_tx(struct atm_dev *dev)
-{
-	struct eni_tx *tx;
-	struct sk_buff *skb;
-	enum enq_res res;
-	int i;
-
-	DPRINTK(">poll_tx\n");
-	for (i = NR_CHAN-1; i >= 0; i--) {
-		tx = &ENI_DEV(dev)->tx[i];
-		if (tx->send)
-			while ((skb = skb_dequeue(&tx->backlog))) {
-				res = do_tx(skb);
-				if (res == enq_ok) continue;
-				DPRINTK("re-queuing TX PDU\n");
-				skb_queue_head(&tx->backlog,skb);
-				requeued++;
-				if (res == enq_jam) return;
-				break;
-			}
-	}
-}
-
-
-static void dequeue_tx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	struct eni_tx *tx;
-
-	NULLCHECK(dev);
-	eni_dev = ENI_DEV(dev);
-	NULLCHECK(eni_dev);
-	while ((skb = skb_dequeue(&eni_dev->tx_queue))) {
-		vcc = ATM_SKB(skb)->vcc;
-		NULLCHECK(vcc);
-		tx = ENI_VCC(vcc)->tx;
-		NULLCHECK(ENI_VCC(vcc)->tx);
-		DPRINTK("dequeue_tx: next 0x%lx curr 0x%x\n",ENI_PRV_POS(skb),
-		    (unsigned) eni_in(MID_TX_DESCRSTART(tx->index)));
-		if (ENI_VCC(vcc)->txing < tx->words && ENI_PRV_POS(skb) ==
-		    eni_in(MID_TX_DESCRSTART(tx->index))) {
-			skb_queue_head(&eni_dev->tx_queue,skb);
-			break;
-		}
-		ENI_VCC(vcc)->txing -= ENI_PRV_SIZE(skb);
-		dma_unmap_single(&eni_dev->pci_dev->dev,ENI_PRV_PADDR(skb),skb->len,
-				 DMA_TO_DEVICE);
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb_irq(skb);
-		atomic_inc(&vcc->stats->tx);
-		wake_up(&eni_dev->tx_wait);
-		dma_complete++;
-	}
-}
-
-
-static struct eni_tx *alloc_tx(struct eni_dev *eni_dev,int ubr)
-{
-	int i;
-
-	for (i = !ubr; i < NR_CHAN; i++)
-		if (!eni_dev->tx[i].send) return eni_dev->tx+i;
-	return NULL;
-}
-
-
-static int comp_tx(struct eni_dev *eni_dev,int *pcr,int reserved,int *pre,
-    int *res,int unlimited)
-{
-	static const int pre_div[] = { 4,16,128,2048 };
-	    /* 2^(((x+2)^2-(x+2))/2+1) */
-
-	if (unlimited) *pre = *res = 0;
-	else {
-		if (*pcr > 0) {
-			int div;
-
-			for (*pre = 0; *pre < 3; (*pre)++)
-				if (TS_CLOCK/pre_div[*pre]/64 <= *pcr) break;
-			div = pre_div[*pre]**pcr;
-			DPRINTK("min div %d\n",div);
-			*res = TS_CLOCK/div-1;
-		}
-		else {
-			int div;
-
-			if (!*pcr) *pcr = eni_dev->tx_bw+reserved;
-			for (*pre = 3; *pre >= 0; (*pre)--)
-				if (TS_CLOCK/pre_div[*pre]/64 > -*pcr) break;
-			if (*pre < 3) (*pre)++; /* else fail later */
-			div = pre_div[*pre]*-*pcr;
-			DPRINTK("max div %d\n",div);
-			*res = DIV_ROUND_UP(TS_CLOCK, div)-1;
-		}
-		if (*res < 0) *res = 0;
-		if (*res > MID_SEG_MAX_RATE) *res = MID_SEG_MAX_RATE;
-	}
-	*pcr = TS_CLOCK/pre_div[*pre]/(*res+1);
-	DPRINTK("out pcr: %d (%d:%d)\n",*pcr,*pre,*res);
-	return 0;
-}
-
-
-static int reserve_or_set_tx(struct atm_vcc *vcc,struct atm_trafprm *txtp,
-    int set_rsv,int set_shp)
-{
-	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
-	struct eni_vcc *eni_vcc = ENI_VCC(vcc);
-	struct eni_tx *tx;
-	unsigned long size;
-	void __iomem *mem;
-	int rate,ubr,unlimited,new_tx;
-	int pre,res,order;
-	int error;
-
-	rate = atm_pcr_goal(txtp);
-	ubr = txtp->traffic_class == ATM_UBR;
-	unlimited = ubr && (!rate || rate <= -ATM_OC3_PCR ||
-	    rate >= ATM_OC3_PCR);
-	if (!unlimited) {
-		size = txtp->max_sdu*eni_dev->tx_mult/100;
-		if (size > MID_MAX_BUF_SIZE && txtp->max_sdu <=
-		    MID_MAX_BUF_SIZE)
-			size = MID_MAX_BUF_SIZE;
-	}
-	else {
-		if (eni_dev->ubr) {
-			eni_vcc->tx = eni_dev->ubr;
-			txtp->pcr = ATM_OC3_PCR;
-			return 0;
-		}
-		size = UBR_BUFFER;
-	}
-	new_tx = !eni_vcc->tx;
-	mem = NULL; /* for gcc */
-	if (!new_tx) tx = eni_vcc->tx;
-	else {
-		mem = eni_alloc_mem(eni_dev,&size);
-		if (!mem) return -ENOBUFS;
-		tx = alloc_tx(eni_dev,unlimited);
-		if (!tx) {
-			eni_free_mem(eni_dev,mem,size);
-			return -EBUSY;
-		}
-		DPRINTK("got chan %d\n",tx->index);
-		tx->reserved = tx->shaping = 0;
-		tx->send = mem;
-		tx->words = size >> 2;
-		skb_queue_head_init(&tx->backlog);
-		for (order = 0; size > (1 << (order+10)); order++);
-		eni_out((order << MID_SIZE_SHIFT) |
-		    ((tx->send-eni_dev->ram) >> (MID_LOC_SKIP+2)),
-		    MID_TX_PLACE(tx->index));
-		tx->tx_pos = eni_in(MID_TX_DESCRSTART(tx->index)) &
-		    MID_DESCR_START;
-	}
-	error = comp_tx(eni_dev,&rate,tx->reserved,&pre,&res,unlimited);
-	if (!error  && txtp->min_pcr > rate) error = -EINVAL;
-	if (!error && txtp->max_pcr && txtp->max_pcr != ATM_MAX_PCR &&
-	    txtp->max_pcr < rate) error = -EINVAL;
-	if (!error && !ubr && rate > eni_dev->tx_bw+tx->reserved)
-		error = -EINVAL;
-	if (!error && set_rsv && !set_shp && rate < tx->shaping)
-		error = -EINVAL;
-	if (!error && !set_rsv && rate > tx->reserved && !ubr)
-		error = -EINVAL;
-	if (error) {
-		if (new_tx) {
-			tx->send = NULL;
-			eni_free_mem(eni_dev,mem,size);
-		}
-		return error;
-	}
-	txtp->pcr = rate;
-	if (set_rsv && !ubr) {
-		eni_dev->tx_bw += tx->reserved;
-		tx->reserved = rate;
-		eni_dev->tx_bw -= rate;
-	}
-	if (set_shp || (unlimited && new_tx)) {
-		if (unlimited && new_tx) eni_dev->ubr = tx;
-		tx->prescaler = pre;
-		tx->resolution = res;
-		tx->shaping = rate;
-	}
-	if (set_shp) eni_vcc->tx = tx;
-	DPRINTK("rsv %d shp %d\n",tx->reserved,tx->shaping);
-	return 0;
-}
-
-
-static int open_tx_first(struct atm_vcc *vcc)
-{
-	ENI_VCC(vcc)->tx = NULL;
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;
-	ENI_VCC(vcc)->txing = 0;
-	return reserve_or_set_tx(vcc,&vcc->qos.txtp,1,1);
-}
-
-
-static int open_tx_second(struct atm_vcc *vcc)
-{
-	return 0; /* nothing to do */
-}
-
-
-static void close_tx(struct atm_vcc *vcc)
-{
-	DECLARE_WAITQUEUE(wait,current);
-	struct eni_dev *eni_dev;
-	struct eni_vcc *eni_vcc;
-
-	eni_vcc = ENI_VCC(vcc);
-	if (!eni_vcc->tx) return;
-	eni_dev = ENI_DEV(vcc->dev);
-	/* wait for TX queue to drain */
-	DPRINTK("eni_close: waiting for TX ...\n");
-	add_wait_queue(&eni_dev->tx_wait,&wait);
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	for (;;) {
-		int txing;
-
-		tasklet_disable(&eni_dev->task);
-		txing = skb_peek(&eni_vcc->tx->backlog) || eni_vcc->txing;
-		tasklet_enable(&eni_dev->task);
-		if (!txing) break;
-		DPRINTK("%d TX left\n",eni_vcc->txing);
-		schedule();
-		set_current_state(TASK_UNINTERRUPTIBLE);
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&eni_dev->tx_wait,&wait);
-	if (eni_vcc->tx != eni_dev->ubr) {
-		/*
-		 * Looping a few times in here is probably far cheaper than
-		 * keeping track of TX completions all the time, so let's poll
-		 * a bit ...
-		 */
-		while (eni_in(MID_TX_RDPTR(eni_vcc->tx->index)) !=
-		    eni_in(MID_TX_DESCRSTART(eni_vcc->tx->index)))
-			schedule();
-		eni_free_mem(eni_dev,eni_vcc->tx->send,eni_vcc->tx->words << 2);
-		eni_vcc->tx->send = NULL;
-		eni_dev->tx_bw += eni_vcc->tx->reserved;
-	}
-	eni_vcc->tx = NULL;
-}
-
-
-static int start_tx(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	int i;
-
-	eni_dev = ENI_DEV(dev);
-	eni_dev->lost = 0;
-	eni_dev->tx_bw = ATM_OC3_PCR;
-	eni_dev->tx_mult = DEFAULT_TX_MULT;
-	init_waitqueue_head(&eni_dev->tx_wait);
-	eni_dev->ubr = NULL;
-	skb_queue_head_init(&eni_dev->tx_queue);
-	eni_out(0,MID_DMA_WR_TX);
-	for (i = 0; i < NR_CHAN; i++) {
-		eni_dev->tx[i].send = NULL;
-		eni_dev->tx[i].index = i;
-	}
-	return 0;
-}
-
-
-/*--------------------------------- common ----------------------------------*/
-
-
-#if 0 /* may become useful again when tuning things */
-
-static void foo(void)
-{
-printk(KERN_INFO
-  "tx_complete=%d,dma_complete=%d,queued=%d,requeued=%d,sub=%d,\n"
-  "backlogged=%d,rx_enqueued=%d,rx_dequeued=%d,putting=%d,pushed=%d\n",
-  tx_complete,dma_complete,queued,requeued,submitted,backlogged,
-  rx_enqueued,rx_dequeued,putting,pushed);
-if (eni_boards) printk(KERN_INFO "loss: %ld\n",ENI_DEV(eni_boards)->lost);
-}
-
-#endif
-
-
-static void bug_int(struct atm_dev *dev,unsigned long reason)
-{
-	DPRINTK(">bug_int\n");
-	if (reason & MID_DMA_ERR_ACK)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
-		    "error\n",dev->number);
-	if (reason & MID_TX_IDENT_MISM)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - ident "
-		    "mismatch\n",dev->number);
-	if (reason & MID_TX_DMA_OVFL)
-		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
-		    "overflow\n",dev->number);
-	EVENT("---dump ends here---\n",0,0);
-	printk(KERN_NOTICE "---recent events---\n");
-	event_dump();
-}
-
-
-static irqreturn_t eni_int(int irq,void *dev_id)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	u32 reason;
-
-	DPRINTK(">eni_int\n");
-	dev = dev_id;
-	eni_dev = ENI_DEV(dev);
-	reason = eni_in(MID_ISA);
-	DPRINTK(DEV_LABEL ": int 0x%lx\n",(unsigned long) reason);
-	/*
-	 * Must handle these two right now, because reading ISA doesn't clear
-	 * them, so they re-occur and we never make it to the tasklet. Since
-	 * they're rare, we don't mind the occasional invocation of eni_tasklet
-	 * with eni_dev->events == 0.
-	 */
-	if (reason & MID_STAT_OVFL) {
-		EVENT("stat overflow\n",0,0);
-		eni_dev->lost += eni_in(MID_STAT) & MID_OVFL_TRASH;
-	}
-	if (reason & MID_SUNI_INT) {
-		EVENT("SUNI int\n",0,0);
-		dev->phy->interrupt(dev);
-#if 0
-		foo();
-#endif
-	}
-	spin_lock(&eni_dev->lock);
-	eni_dev->events |= reason;
-	spin_unlock(&eni_dev->lock);
-	tasklet_schedule(&eni_dev->task);
-	return IRQ_HANDLED;
-}
-
-
-static void eni_tasklet(unsigned long data)
-{
-	struct atm_dev *dev = (struct atm_dev *) data;
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-	unsigned long flags;
-	u32 events;
-
-	DPRINTK("eni_tasklet (dev %p)\n",dev);
-	spin_lock_irqsave(&eni_dev->lock,flags);
-	events = xchg(&eni_dev->events,0);
-	spin_unlock_irqrestore(&eni_dev->lock,flags);
-	if (events & MID_RX_DMA_COMPLETE) {
-		EVENT("INT: RX DMA complete, starting dequeue_rx\n",0,0);
-		dequeue_rx(dev);
-		EVENT("dequeue_rx done, starting poll_rx\n",0,0);
-		poll_rx(dev);
-		EVENT("poll_rx done\n",0,0);
-		/* poll_tx ? */
-	}
-	if (events & MID_SERVICE) {
-		EVENT("INT: service, starting get_service\n",0,0);
-		get_service(dev);
-		EVENT("get_service done, starting poll_rx\n",0,0);
-		poll_rx(dev);
-		EVENT("poll_rx done\n",0,0);
-	}
- 	if (events & MID_TX_DMA_COMPLETE) {
-		EVENT("INT: TX DMA COMPLETE\n",0,0);
-		dequeue_tx(dev);
-	}
-	if (events & MID_TX_COMPLETE) {
-		EVENT("INT: TX COMPLETE\n",0,0);
-		tx_complete++;
-		wake_up(&eni_dev->tx_wait);
-		/* poll_rx ? */
-	}
-	if (events & (MID_DMA_ERR_ACK | MID_TX_IDENT_MISM | MID_TX_DMA_OVFL)) {
-		EVENT("bug interrupt\n",0,0);
-		bug_int(dev,events);
-	}
-	poll_tx(dev);
-}
-
-
-/*--------------------------------- entries ---------------------------------*/
-
-
-static char * const media_name[] = {
-    "MMF", "SMF", "MMF", "03?", /*  0- 3 */
-    "UTP", "05?", "06?", "07?", /*  4- 7 */
-    "TAXI","09?", "10?", "11?", /*  8-11 */
-    "12?", "13?", "14?", "15?", /* 12-15 */
-    "MMF", "SMF", "18?", "19?", /* 16-19 */
-    "UTP", "21?", "22?", "23?", /* 20-23 */
-    "24?", "25?", "26?", "27?", /* 24-27 */
-    "28?", "29?", "30?", "31?"  /* 28-31 */
-};
-
-
-#define SET_SEPROM \
-  ({ if (!error && !pci_error) { \
-    pci_error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,tonga); \
-    udelay(10); /* 10 usecs */ \
-  } })
-#define GET_SEPROM \
-  ({ if (!error && !pci_error) { \
-    pci_error = pci_read_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,&tonga); \
-    udelay(10); /* 10 usecs */ \
-  } })
-
-
-static int get_esi_asic(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	unsigned char tonga;
-	int error,failed,pci_error;
-	int address,i,j;
-
-	eni_dev = ENI_DEV(dev);
-	error = pci_error = 0;
-	tonga = SEPROM_MAGIC | SEPROM_DATA | SEPROM_CLK;
-	SET_SEPROM;
-	for (i = 0; i < ESI_LEN && !error && !pci_error; i++) {
-		/* start operation */
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		tonga &= ~SEPROM_DATA;
-		SET_SEPROM;
-		tonga &= ~SEPROM_CLK;
-		SET_SEPROM;
-		/* send address */
-		address = ((i+SEPROM_ESI_BASE) << 1)+1;
-		for (j = 7; j >= 0; j--) {
-			tonga = (address >> j) & 1 ? tonga | SEPROM_DATA :
-			    tonga & ~SEPROM_DATA;
-			SET_SEPROM;
-			tonga |= SEPROM_CLK;
-			SET_SEPROM;
-			tonga &= ~SEPROM_CLK;
-			SET_SEPROM;
-		}
-		/* get ack */
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		GET_SEPROM;
-		failed = tonga & SEPROM_DATA;
-		tonga &= ~SEPROM_CLK;
-		SET_SEPROM;
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-		if (failed) error = -EIO;
-		else {
-			dev->esi[i] = 0;
-			for (j = 7; j >= 0; j--) {
-				dev->esi[i] <<= 1;
-				tonga |= SEPROM_DATA;
-				SET_SEPROM;
-				tonga |= SEPROM_CLK;
-				SET_SEPROM;
-				GET_SEPROM;
-				if (tonga & SEPROM_DATA) dev->esi[i] |= 1;
-				tonga &= ~SEPROM_CLK;
-				SET_SEPROM;
-				tonga |= SEPROM_DATA;
-				SET_SEPROM;
-			}
-			/* get ack */
-			tonga |= SEPROM_DATA;
-			SET_SEPROM;
-			tonga |= SEPROM_CLK;
-			SET_SEPROM;
-			GET_SEPROM;
-			if (!(tonga & SEPROM_DATA)) error = -EIO;
-			tonga &= ~SEPROM_CLK;
-			SET_SEPROM;
-			tonga |= SEPROM_DATA;
-			SET_SEPROM;
-		}
-		/* stop operation */
-		tonga &= ~SEPROM_DATA;
-		SET_SEPROM;
-		tonga |= SEPROM_CLK;
-		SET_SEPROM;
-		tonga |= SEPROM_DATA;
-		SET_SEPROM;
-	}
-	if (pci_error) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): error reading ESI "
-		    "(0x%02x)\n",dev->number,pci_error);
-		error = -EIO;
-	}
-	return error;
-}
-
-
-#undef SET_SEPROM
-#undef GET_SEPROM
-
-
-static int get_esi_fpga(struct atm_dev *dev, void __iomem *base)
-{
-	void __iomem *mac_base;
-	int i;
-
-	mac_base = base+EPROM_SIZE-sizeof(struct midway_eprom);
-	for (i = 0; i < ESI_LEN; i++) dev->esi[i] = readb(mac_base+(i^3));
-	return 0;
-}
-
-
-static int eni_do_init(struct atm_dev *dev)
-{
-	struct midway_eprom __iomem *eprom;
-	struct eni_dev *eni_dev;
-	struct pci_dev *pci_dev;
-	unsigned long real_base;
-	void __iomem *base;
-	int error,i,last;
-
-	DPRINTK(">eni_init\n");
-	dev->ci_range.vpi_bits = 0;
-	dev->ci_range.vci_bits = NR_VCI_LD;
-	dev->link_rate = ATM_OC3_PCR;
-	eni_dev = ENI_DEV(dev);
-	pci_dev = eni_dev->pci_dev;
-	real_base = pci_resource_start(pci_dev, 0);
-	eni_dev->irq = pci_dev->irq;
-	if ((error = pci_write_config_word(pci_dev,PCI_COMMAND,
-	    PCI_COMMAND_MEMORY |
-	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory "
-		    "(0x%02x)\n",dev->number,error);
-		return -EIO;
-	}
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d,base=0x%lx,irq=%d,",
-	    dev->number,pci_dev->revision,real_base,eni_dev->irq);
-	if (!(base = ioremap(real_base,MAP_MAX_SIZE))) {
-		printk("\n");
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't set up page "
-		    "mapping\n",dev->number);
-		return -ENOMEM;
-	}
-	eni_dev->ioaddr = base;
-	eni_dev->base_diff = real_base - (unsigned long) base;
-	/* id may not be present in ASIC Tonga boards - check this @@@ */
-	if (!eni_dev->asic) {
-		eprom = (base+EPROM_SIZE-sizeof(struct midway_eprom));
-		if (readl(&eprom->magic) != ENI155_MAGIC) {
-			printk("\n");
-			printk(KERN_ERR DEV_LABEL
-			       "(itf %d): bad magic - expected 0x%x, got 0x%x\n",
-			       dev->number, ENI155_MAGIC,
-			       (unsigned)readl(&eprom->magic));
-			error = -EINVAL;
-			goto unmap;
-		}
-	}
-	eni_dev->phy = base+PHY_BASE;
-	eni_dev->reg = base+REG_BASE;
-	eni_dev->ram = base+RAM_BASE;
-	last = MAP_MAX_SIZE-RAM_BASE;
-	for (i = last-RAM_INCREMENT; i >= 0; i -= RAM_INCREMENT) {
-		writel(0x55555555,eni_dev->ram+i);
-		if (readl(eni_dev->ram+i) != 0x55555555) last = i;
-		else {
-			writel(0xAAAAAAAA,eni_dev->ram+i);
-			if (readl(eni_dev->ram+i) != 0xAAAAAAAA) last = i;
-			else writel(i,eni_dev->ram+i);
-		}
-	}
-	for (i = 0; i < last; i += RAM_INCREMENT)
-		if (readl(eni_dev->ram+i) != i) break;
-	eni_dev->mem = i;
-	memset_io(eni_dev->ram,0,eni_dev->mem);
-	/* TODO: should shrink allocation now */
-	printk("mem=%dkB (",eni_dev->mem >> 10);
-	/* TODO: check for non-SUNI, check for TAXI ? */
-	if (!(eni_in(MID_RES_ID_MCON) & 0x200) != !eni_dev->asic) {
-		printk(")\n");
-		printk(KERN_ERR DEV_LABEL "(itf %d): ERROR - wrong id 0x%x\n",
-		    dev->number,(unsigned) eni_in(MID_RES_ID_MCON));
-		error = -EINVAL;
-		goto unmap;
-	}
-	error = eni_dev->asic ? get_esi_asic(dev) : get_esi_fpga(dev,base);
-	if (error)
-		goto unmap;
-	for (i = 0; i < ESI_LEN; i++)
-		printk("%s%02X",i ? "-" : "",dev->esi[i]);
-	printk(")\n");
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): %s,%s\n",dev->number,
-	    eni_in(MID_RES_ID_MCON) & 0x200 ? "ASIC" : "FPGA",
-	    media_name[eni_in(MID_RES_ID_MCON) & DAUGHTER_ID]);
-
-	error = suni_init(dev);
-	if (error)
-		goto unmap;
-out:
-	return error;
-unmap:
-	iounmap(base);
-	goto out;
-}
-
-static void eni_do_release(struct atm_dev *dev)
-{
-	struct eni_dev *ed = ENI_DEV(dev);
-
-	dev->phy->stop(dev);
-	dev->phy = NULL;
-	iounmap(ed->ioaddr);
-}
-
-static int eni_start(struct atm_dev *dev)
-{
-	struct eni_dev *eni_dev;
-	
-	void __iomem *buf;
-	unsigned long buffer_mem;
-	int error;
-
-	DPRINTK(">eni_start\n");
-	eni_dev = ENI_DEV(dev);
-	if (request_irq(eni_dev->irq,&eni_int,IRQF_SHARED,DEV_LABEL,dev)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
-		    dev->number,eni_dev->irq);
-		error = -EAGAIN;
-		goto out;
-	}
-	pci_set_master(eni_dev->pci_dev);
-	if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
-	    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"
-		    "master (0x%02x)\n",dev->number,error);
-		goto free_irq;
-	}
-	if ((error = pci_write_config_byte(eni_dev->pci_dev,PCI_TONGA_CTRL,
-	    END_SWAP_DMA))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't set endian swap "
-		    "(0x%02x)\n",dev->number,error);
-		goto free_irq;
-	}
-	/* determine addresses of internal tables */
-	eni_dev->vci = eni_dev->ram;
-	eni_dev->rx_dma = eni_dev->ram+NR_VCI*16;
-	eni_dev->tx_dma = eni_dev->rx_dma+NR_DMA_RX*8;
-	eni_dev->service = eni_dev->tx_dma+NR_DMA_TX*8;
-	buf = eni_dev->service+NR_SERVICE*4;
-	DPRINTK("vci 0x%lx,rx 0x%lx, tx 0x%lx,srv 0x%lx,buf 0x%lx\n",
-	     eni_dev->vci,eni_dev->rx_dma,eni_dev->tx_dma,
-	     eni_dev->service,buf);
-	spin_lock_init(&eni_dev->lock);
-	tasklet_init(&eni_dev->task,eni_tasklet,(unsigned long) dev);
-	eni_dev->events = 0;
-	/* initialize memory management */
-	buffer_mem = eni_dev->mem - (buf - eni_dev->ram);
-	eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2;
-	eni_dev->free_list = kmalloc_objs(*eni_dev->free_list,
-					  eni_dev->free_list_size + 1);
-	if (!eni_dev->free_list) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n",
-		    dev->number);
-		error = -ENOMEM;
-		goto free_irq;
-	}
-	eni_dev->free_len = 0;
-	eni_put_free(eni_dev,buf,buffer_mem);
-	memset_io(eni_dev->vci,0,16*NR_VCI); /* clear VCI table */
-	/*
-	 * byte_addr  free (k)
-	 * 0x00000000     512  VCI table
-	 * 0x00004000	  496  RX DMA
-	 * 0x00005000	  492  TX DMA
-	 * 0x00006000	  488  service list
-	 * 0x00007000	  484  buffers
-	 * 0x00080000	    0  end (512kB)
-	 */
-	eni_out(0xffffffff,MID_IE);
-	error = start_tx(dev);
-	if (error) goto free_list;
-	error = start_rx(dev);
-	if (error) goto free_list;
-	error = dev->phy->start(dev);
-	if (error) goto free_list;
-	eni_out(eni_in(MID_MC_S) | (1 << MID_INT_SEL_SHIFT) |
-	    MID_TX_LOCK_MODE | MID_DMA_ENABLE | MID_TX_ENABLE | MID_RX_ENABLE,
-	    MID_MC_S);
-	    /* Tonga uses SBus INTReq1 */
-	(void) eni_in(MID_ISA); /* clear Midway interrupts */
-	return 0;
-
-free_list:
-	kfree(eni_dev->free_list);
-
-free_irq:
-	free_irq(eni_dev->irq, dev);
-
-out:
-	return error;
-}
-
-
-static void eni_close(struct atm_vcc *vcc)
-{
-	DPRINTK(">eni_close\n");
-	if (!ENI_VCC(vcc)) return;
-	clear_bit(ATM_VF_READY,&vcc->flags);
-	close_rx(vcc);
-	close_tx(vcc);
-	DPRINTK("eni_close: done waiting\n");
-	/* deallocate memory */
-	kfree(ENI_VCC(vcc));
-	vcc->dev_data = NULL;
-	clear_bit(ATM_VF_ADDR,&vcc->flags);
-	/*foo();*/
-}
-
-
-static int eni_open(struct atm_vcc *vcc)
-{
-	struct eni_vcc *eni_vcc;
-	int error;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	DPRINTK(">eni_open\n");
-	EVENT("eni_open\n",0,0);
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
-		vcc->dev_data = NULL;
-	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
-		set_bit(ATM_VF_ADDR,&vcc->flags);
-	if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
-		return -EINVAL;
-	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi,
-	    vcc->vci);
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
-		eni_vcc = kmalloc_obj(struct eni_vcc);
-		if (!eni_vcc) return -ENOMEM;
-		vcc->dev_data = eni_vcc;
-		eni_vcc->tx = NULL; /* for eni_close after open_rx */
-		if ((error = open_rx_first(vcc))) {
-			eni_close(vcc);
-			return error;
-		}
-		if ((error = open_tx_first(vcc))) {
-			eni_close(vcc);
-			return error;
-		}
-	}
-	if (vci == ATM_VPI_UNSPEC || vpi == ATM_VCI_UNSPEC) return 0;
-	if ((error = open_rx_second(vcc))) {
-		eni_close(vcc);
-		return error;
-	}
-	if ((error = open_tx_second(vcc))) {
-		eni_close(vcc);
-		return error;
-	}
-	set_bit(ATM_VF_READY,&vcc->flags);
-	/* should power down SUNI while !ref_count @@@ */
-	return 0;
-}
-
-
-static int eni_change_qos(struct atm_vcc *vcc,struct atm_qos *qos,int flgs)
-{
-	struct eni_dev *eni_dev = ENI_DEV(vcc->dev);
-	struct eni_tx *tx = ENI_VCC(vcc)->tx;
-	struct sk_buff *skb;
-	int error,rate,rsv,shp;
-
-	if (qos->txtp.traffic_class == ATM_NONE) return 0;
-	if (tx == eni_dev->ubr) return -EBADFD;
-	rate = atm_pcr_goal(&qos->txtp);
-	if (rate < 0) rate = -rate;
-	rsv = shp = 0;
-	if ((flgs & ATM_MF_DEC_RSV) && rate && rate < tx->reserved) rsv = 1;
-	if ((flgs & ATM_MF_INC_RSV) && (!rate || rate > tx->reserved)) rsv = 1;
-	if ((flgs & ATM_MF_DEC_SHP) && rate && rate < tx->shaping) shp = 1;
-	if ((flgs & ATM_MF_INC_SHP) && (!rate || rate > tx->shaping)) shp = 1;
-	if (!rsv && !shp) return 0;
-	error = reserve_or_set_tx(vcc,&qos->txtp,rsv,shp);
-	if (error) return error;
-	if (shp && !(flgs & ATM_MF_IMMED)) return 0;
-	/*
-	 * Walk through the send buffer and patch the rate information in all
-	 * segmentation buffer descriptors of this VCC.
-	 */
-	tasklet_disable(&eni_dev->task);
-	skb_queue_walk(&eni_dev->tx_queue, skb) {
-		void __iomem *dsc;
-
-		if (ATM_SKB(skb)->vcc != vcc) continue;
-		dsc = tx->send+ENI_PRV_POS(skb)*4;
-		writel((readl(dsc) & ~(MID_SEG_RATE | MID_SEG_PR)) |
-		    (tx->prescaler << MID_SEG_PR_SHIFT) |
-		    (tx->resolution << MID_SEG_RATE_SHIFT), dsc);
-	}
-	tasklet_enable(&eni_dev->task);
-	return 0;
-}
-
-
-static int eni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-
-	if (cmd == ENI_MEMDUMP) {
-		if (!capable(CAP_NET_ADMIN)) return -EPERM;
-		printk(KERN_WARNING "Please use /proc/atm/" DEV_LABEL ":%d "
-		    "instead of obsolete ioctl ENI_MEMDUMP\n",dev->number);
-		dump(dev);
-		return 0;
-	}
-	if (cmd == ENI_SETMULT) {
-		struct eni_multipliers mult;
-
-		if (!capable(CAP_NET_ADMIN)) return -EPERM;
-		if (copy_from_user(&mult, arg,
-		    sizeof(struct eni_multipliers)))
-			return -EFAULT;
-		if ((mult.tx && mult.tx <= 100) || (mult.rx &&mult.rx <= 100) ||
-		    mult.tx > 65536 || mult.rx > 65536)
-			return -EINVAL;
-		if (mult.tx) eni_dev->tx_mult = mult.tx;
-		if (mult.rx) eni_dev->rx_mult = mult.rx;
-		return 0;
-	}
-	if (cmd == ATM_SETCIRANGE) {
-		struct atm_cirange ci;
-
-		if (copy_from_user(&ci, arg,sizeof(struct atm_cirange)))
-			return -EFAULT;
-		if ((ci.vpi_bits == 0 || ci.vpi_bits == ATM_CI_MAX) &&
-		    (ci.vci_bits == NR_VCI_LD || ci.vpi_bits == ATM_CI_MAX))
-		    return 0;
-		return -EINVAL;
-	}
-	if (!dev->phy->ioctl) return -ENOIOCTLCMD;
-	return dev->phy->ioctl(dev,cmd,arg);
-}
-
-static int eni_send(struct atm_vcc *vcc,struct sk_buff *skb)
-{
-	enum enq_res res;
-
-	DPRINTK(">eni_send\n");
-	if (!ENI_VCC(vcc)->tx) {
-		if (vcc->pop) vcc->pop(vcc,skb);
-		else dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	if (!skb) {
-		printk(KERN_CRIT "!skb in eni_send ?\n");
-		if (vcc->pop) vcc->pop(vcc,skb);
-		return -EINVAL;
-	}
-	if (vcc->qos.aal == ATM_AAL0) {
-		if (skb->len != ATM_CELL_SIZE-1) {
-			if (vcc->pop) vcc->pop(vcc,skb);
-			else dev_kfree_skb(skb);
-			return -EINVAL;
-		}
-		*(u32 *) skb->data = htonl(*(u32 *) skb->data);
-	}
-	submitted++;
-	ATM_SKB(skb)->vcc = vcc;
-	tasklet_disable_in_atomic(&ENI_DEV(vcc->dev)->task);
-	res = do_tx(skb);
-	tasklet_enable(&ENI_DEV(vcc->dev)->task);
-	if (res == enq_ok) return 0;
-	skb_queue_tail(&ENI_VCC(vcc)->tx->backlog,skb);
-	backlogged++;
-	tasklet_schedule(&ENI_DEV(vcc->dev)->task);
-	return 0;
-}
-
-static void eni_phy_put(struct atm_dev *dev,unsigned char value,
-    unsigned long addr)
-{
-	writel(value,ENI_DEV(dev)->phy+addr*4);
-}
-
-
-
-static unsigned char eni_phy_get(struct atm_dev *dev,unsigned long addr)
-{
-	return readl(ENI_DEV(dev)->phy+addr*4);
-}
-
-
-static int eni_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
-{
-	struct sock *s;
-	static const char *signal[] = { "LOST","unknown","okay" };
-	struct eni_dev *eni_dev = ENI_DEV(dev);
-	struct atm_vcc *vcc;
-	int left,i;
-
-	left = *pos;
-	if (!left)
-		return sprintf(page,DEV_LABEL "(itf %d) signal %s, %dkB, "
-		    "%d cps remaining\n",dev->number,signal[(int) dev->signal],
-		    eni_dev->mem >> 10,eni_dev->tx_bw);
-	if (!--left)
-		return sprintf(page,"%4sBursts: TX"
-#if !defined(CONFIG_ATM_ENI_BURST_TX_16W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_8W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_4W) && \
-    !defined(CONFIG_ATM_ENI_BURST_TX_2W)
-		    " none"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_16W
-		    " 16W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_8W
-		    " 8W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_4W
-		    " 4W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_TX_2W
-		    " 2W"
-#endif
-		    ", RX"
-#if !defined(CONFIG_ATM_ENI_BURST_RX_16W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_8W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_4W) && \
-    !defined(CONFIG_ATM_ENI_BURST_RX_2W)
-		    " none"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_16W
-		    " 16W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_8W
-		    " 8W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_4W
-		    " 4W"
-#endif
-#ifdef CONFIG_ATM_ENI_BURST_RX_2W
-		    " 2W"
-#endif
-#ifndef CONFIG_ATM_ENI_TUNE_BURST
-		    " (default)"
-#endif
-		    "\n","");
-	if (!--left) 
-		return sprintf(page,"%4sBuffer multipliers: tx %d%%, rx %d%%\n",
-		    "",eni_dev->tx_mult,eni_dev->rx_mult);
-	for (i = 0; i < NR_CHAN; i++) {
-		struct eni_tx *tx = eni_dev->tx+i;
-
-		if (!tx->send) continue;
-		if (!--left) {
-			return sprintf(page, "tx[%d]:    0x%lx-0x%lx "
-			    "(%6ld bytes), rsv %d cps, shp %d cps%s\n",i,
-			    (unsigned long) (tx->send - eni_dev->ram),
-			    tx->send-eni_dev->ram+tx->words*4-1,tx->words*4,
-			    tx->reserved,tx->shaping,
-			    tx == eni_dev->ubr ? " (UBR)" : "");
-		}
-		if (--left) continue;
-		return sprintf(page,"%10sbacklog %u packets\n","",
-		    skb_queue_len(&tx->backlog));
-	}
-	read_lock(&vcc_sklist_lock);
-	for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
-		struct hlist_head *head = &vcc_hash[i];
-
-		sk_for_each(s, head) {
-			struct eni_vcc *eni_vcc;
-			int length;
-
-			vcc = atm_sk(s);
-			if (vcc->dev != dev)
-				continue;
-			eni_vcc = ENI_VCC(vcc);
-			if (--left) continue;
-			length = sprintf(page,"vcc %4d: ",vcc->vci);
-			if (eni_vcc->rx) {
-				length += sprintf(page+length, "0x%lx-0x%lx "
-				    "(%6ld bytes)",
-				    (unsigned long) (eni_vcc->recv - eni_dev->ram),
-				    eni_vcc->recv-eni_dev->ram+eni_vcc->words*4-1,
-				    eni_vcc->words*4);
-				if (eni_vcc->tx) length += sprintf(page+length,", ");
-			}
-			if (eni_vcc->tx)
-				length += sprintf(page+length,"tx[%d], txing %d bytes",
-				    eni_vcc->tx->index,eni_vcc->txing);
-			page[length] = '\n';
-			read_unlock(&vcc_sklist_lock);
-			return length+1;
-		}
-	}
-	read_unlock(&vcc_sklist_lock);
-	for (i = 0; i < eni_dev->free_len; i++) {
-		struct eni_free *fe = eni_dev->free_list+i;
-		unsigned long offset;
-
-		if (--left) continue;
-		offset = (unsigned long) eni_dev->ram+eni_dev->base_diff;
-		return sprintf(page,"free      %p-%p (%6d bytes)\n",
-		    fe->start-offset,fe->start-offset+(1 << fe->order)-1,
-		    1 << fe->order);
-	}
-	return 0;
-}
-
-
-static const struct atmdev_ops ops = {
-	.open		= eni_open,
-	.close		= eni_close,
-	.ioctl		= eni_ioctl,
-	.send		= eni_send,
-	.phy_put	= eni_phy_put,
-	.phy_get	= eni_phy_get,
-	.change_qos	= eni_change_qos,
-	.proc_read	= eni_proc_read
-};
-
-
-static int eni_init_one(struct pci_dev *pci_dev,
-			const struct pci_device_id *ent)
-{
-	struct atm_dev *dev;
-	struct eni_dev *eni_dev;
-	struct eni_zero *zero;
-	int rc;
-
-	rc = pci_enable_device(pci_dev);
-	if (rc < 0)
-		goto out;
-
-	rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
-	if (rc < 0)
-		goto err_disable;
-
-	rc = -ENOMEM;
-	eni_dev = kmalloc_obj(struct eni_dev);
-	if (!eni_dev)
-		goto err_disable;
-
-	zero = &eni_dev->zero;
-	zero->addr = dma_alloc_coherent(&pci_dev->dev,
-					ENI_ZEROES_SIZE, &zero->dma, GFP_KERNEL);
-	if (!zero->addr)
-		goto err_kfree;
-
-	dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL);
-	if (!dev)
-		goto err_free_consistent;
-
-	dev->dev_data = eni_dev;
-	pci_set_drvdata(pci_dev, dev);
-	eni_dev->pci_dev = pci_dev;
-	eni_dev->asic = ent->driver_data;
-
-	rc = eni_do_init(dev);
-	if (rc < 0)
-		goto err_unregister;
-
-	rc = eni_start(dev);
-	if (rc < 0)
-		goto err_eni_release;
-
-	eni_dev->more = eni_boards;
-	eni_boards = dev;
-out:
-	return rc;
-
-err_eni_release:
-	dev->phy = NULL;
-	iounmap(ENI_DEV(dev)->ioaddr);
-err_unregister:
-	atm_dev_deregister(dev);
-err_free_consistent:
-	dma_free_coherent(&pci_dev->dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
-err_kfree:
-	kfree(eni_dev);
-err_disable:
-	pci_disable_device(pci_dev);
-	goto out;
-}
-
-
-static const struct pci_device_id eni_pci_tbl[] = {
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_FPGA), 0 /* FPGA */ },
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_ASIC), 1 /* ASIC */ },
-	{ 0, }
-};
-MODULE_DEVICE_TABLE(pci,eni_pci_tbl);
-
-
-static void eni_remove_one(struct pci_dev *pdev)
-{
-	struct atm_dev *dev = pci_get_drvdata(pdev);
-	struct eni_dev *ed = ENI_DEV(dev);
-	struct eni_zero *zero = &ed->zero;
-
-	eni_do_release(dev);
-	atm_dev_deregister(dev);
-	dma_free_coherent(&pdev->dev, ENI_ZEROES_SIZE, zero->addr, zero->dma);
-	kfree(ed);
-	pci_disable_device(pdev);
-}
-
-
-static struct pci_driver eni_driver = {
-	.name		= DEV_LABEL,
-	.id_table	= eni_pci_tbl,
-	.probe		= eni_init_one,
-	.remove		= eni_remove_one,
-};
-
-
-static int __init eni_init(void)
-{
-	struct sk_buff *skb; /* dummy for sizeof */
-
-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct eni_skb_prv));
-	return pci_register_driver(&eni_driver);
-}
-
-
-module_init(eni_init);
-/* @@@ since exit routine not defined, this module can not be unloaded */
-
-MODULE_DESCRIPTION("Efficient Networks ENI155P ATM NIC driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/eni.h b/drivers/atm/eni.h
deleted file mode 100644
index de1ed80..0000000
--- a/drivers/atm/eni.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
- 
- 
-#ifndef DRIVER_ATM_ENI_H
-#define DRIVER_ATM_ENI_H
-
-#include <linux/atm.h>
-#include <linux/atmdev.h>
-#include <linux/interrupt.h>
-#include <linux/sonet.h>
-#include <linux/skbuff.h>
-#include <linux/time.h>
-#include <linux/pci.h>
-#include <linux/spinlock.h>
-#include <linux/atomic.h>
-
-#include "midway.h"
-
-
-#define DEV_LABEL	"eni"
-
-#define UBR_BUFFER	(128*1024)	/* UBR buffer size */
-
-#define RX_DMA_BUF	  8		/* burst and skip a few things */
-#define TX_DMA_BUF	100		/* should be enough for 64 kB */
-
-#define DEFAULT_RX_MULT	300		/* max_sdu*3 */
-#define DEFAULT_TX_MULT	300		/* max_sdu*3 */
-
-#define ENI_ZEROES_SIZE	  4		/* need that many DMA-able zero bytes */
-
-
-struct eni_free {
-	void __iomem *start;		/* counting in bytes */
-	int order;
-};
-
-struct eni_tx {
-	void __iomem *send;		/* base, 0 if unused */
-	int prescaler;			/* shaping prescaler */
-	int resolution;			/* shaping divider */
-	unsigned long tx_pos;		/* current TX write position */
-	unsigned long words;		/* size of TX queue */
-	int index;			/* TX channel number */
-	int reserved;			/* reserved peak cell rate */
-	int shaping;			/* shaped peak cell rate */
-	struct sk_buff_head backlog;	/* queue of waiting TX buffers */
-};
-
-struct eni_vcc {
-	int (*rx)(struct atm_vcc *vcc);	/* RX function, NULL if none */
-	void __iomem *recv;		/* receive buffer */
-	unsigned long words;		/* its size in words */
-	unsigned long descr;		/* next descriptor (RX) */
-	unsigned long rx_pos;		/* current RX descriptor pos */
-	struct eni_tx *tx;		/* TXer, NULL if none */
-	int rxing;			/* number of pending PDUs */
-	int servicing;			/* number of waiting VCs (0 or 1) */
-	int txing;			/* number of pending TX bytes */
-	ktime_t timestamp;		/* for RX timing */
-	struct atm_vcc *next;		/* next pending RX */
-	struct sk_buff *last;		/* last PDU being DMAed (used to carry
-					   discard information) */
-};
-
-struct eni_dev {
-	/*-------------------------------- spinlock */
-	spinlock_t lock;		/* sync with interrupt */
-	struct tasklet_struct task;	/* tasklet for interrupt work */
-	u32 events;			/* pending events */
-	/*-------------------------------- base pointers into Midway address
-					   space */
-	void __iomem *ioaddr;
-	void __iomem *phy;		/* PHY interface chip registers */
-	void __iomem *reg;		/* register base */
-	void __iomem *ram;		/* RAM base */
-	void __iomem *vci;		/* VCI table */
-	void __iomem *rx_dma;		/* RX DMA queue */
-	void __iomem *tx_dma;		/* TX DMA queue */
-	void __iomem *service;		/* service list */
-	/*-------------------------------- TX part */
-	struct eni_tx tx[NR_CHAN];	/* TX channels */
-	struct eni_tx *ubr;		/* UBR channel */
-	struct sk_buff_head tx_queue;	/* PDUs currently being TX DMAed*/
-	wait_queue_head_t tx_wait;	/* for close */
-	int tx_bw;			/* remaining bandwidth */
-	u32 dma[TX_DMA_BUF*2];		/* DMA request scratch area */
-	struct eni_zero {		/* aligned "magic" zeroes */
-		u32 *addr;
-		dma_addr_t dma;
-	} zero;
-	int tx_mult;			/* buffer size multiplier (percent) */
-	/*-------------------------------- RX part */
-	u32 serv_read;			/* host service read index */
-	struct atm_vcc *fast,*last_fast;/* queues of VCCs with pending PDUs */
-	struct atm_vcc *slow,*last_slow;
-	struct atm_vcc **rx_map;	/* for fast lookups */
-	struct sk_buff_head rx_queue;	/* PDUs currently being RX-DMAed */
-	wait_queue_head_t rx_wait;	/* for close */
-	int rx_mult;			/* buffer size multiplier (percent) */
-	/*-------------------------------- statistics */
-	unsigned long lost;		/* number of lost cells (RX) */
-	/*-------------------------------- memory management */
-	unsigned long base_diff;	/* virtual-real base address */
-	int free_len;			/* free list length */
-	struct eni_free *free_list;	/* free list */
-	int free_list_size;		/* maximum size of free list */
-	/*-------------------------------- ENI links */
-	struct atm_dev *more;		/* other ENI devices */
-	/*-------------------------------- general information */
-	int mem;			/* RAM on board (in bytes) */
-	int asic;			/* PCI interface type, 0 for FPGA */
-	unsigned int irq;		/* IRQ */
-	struct pci_dev *pci_dev;	/* PCI stuff */
-};
-
-
-#define ENI_DEV(d) ((struct eni_dev *) (d)->dev_data)
-#define ENI_VCC(d) ((struct eni_vcc *) (d)->dev_data)
-
-
-struct eni_skb_prv {
-	struct atm_skb_data _;		/* reserved */
-	unsigned long pos;		/* position of next descriptor */
-	int size;			/* PDU size in reassembly buffer */
-	dma_addr_t paddr;		/* DMA handle */
-};
-
-#define ENI_PRV_SIZE(skb) (((struct eni_skb_prv *) (skb)->cb)->size)
-#define ENI_PRV_POS(skb) (((struct eni_skb_prv *) (skb)->cb)->pos)
-#define ENI_PRV_PADDR(skb) (((struct eni_skb_prv *) (skb)->cb)->paddr)
-
-#endif
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
deleted file mode 100644
index 2423eed..0000000
--- a/drivers/atm/fore200e.c
+++ /dev/null
@@ -1,3012 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-  A FORE Systems 200E-series driver for ATM on Linux.
-  Christophe Lizzi (lizzi@cnam.fr), October 1999-March 2003.
-
-  Based on the PCA-200E driver from Uwe Dannowski (Uwe.Dannowski@inf.tu-dresden.de).
-
-  This driver simultaneously supports PCA-200E and SBA-200E adapters
-  on i386, alpha (untested), powerpc, sparc and sparc64 architectures.
-
-*/
-
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/firmware.h>
-#include <linux/pgtable.h>
-#include <asm/io.h>
-#include <asm/string.h>
-#include <asm/page.h>
-#include <asm/irq.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-#ifdef CONFIG_SBUS
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <asm/idprom.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-#endif
-
-#if defined(CONFIG_ATM_FORE200E_USE_TASKLET) /* defer interrupt work to a tasklet */
-#define FORE200E_USE_TASKLET
-#endif
-
-#if 0 /* enable the debugging code of the buffer supply queues */
-#define FORE200E_BSQ_DEBUG
-#endif
-
-#if 1 /* ensure correct handling of 52-byte AAL0 SDUs expected by atmdump-like apps */
-#define FORE200E_52BYTE_AAL0_SDU
-#endif
-
-#include "fore200e.h"
-#include "suni.h"
-
-#define FORE200E_VERSION "0.3e"
-
-#define FORE200E         "fore200e: "
-
-#if 0 /* override .config */
-#define CONFIG_ATM_FORE200E_DEBUG 1
-#endif
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
-#define DPRINTK(level, format, args...)  do { if (CONFIG_ATM_FORE200E_DEBUG >= (level)) \
-                                                  printk(FORE200E format, ##args); } while (0)
-#else
-#define DPRINTK(level, format, args...)  do {} while (0)
-#endif
-
-
-#define FORE200E_ALIGN(addr, alignment) \
-        ((((unsigned long)(addr) + (alignment - 1)) & ~(alignment - 1)) - (unsigned long)(addr))
-
-#define FORE200E_DMA_INDEX(dma_addr, type, index)  ((dma_addr) + (index) * sizeof(type))
-
-#define FORE200E_INDEX(virt_addr, type, index)     (&((type *)(virt_addr))[ index ])
-
-#define FORE200E_NEXT_ENTRY(index, modulo)         (index = ((index) + 1) % (modulo))
-
-#if 1
-#define ASSERT(expr)     if (!(expr)) { \
-			     printk(FORE200E "assertion failed! %s[%d]: %s\n", \
-				    __func__, __LINE__, #expr); \
-			     panic(FORE200E "%s", __func__); \
-			 }
-#else
-#define ASSERT(expr)     do {} while (0)
-#endif
-
-
-static const struct atmdev_ops   fore200e_ops;
-
-MODULE_AUTHOR("Christophe Lizzi - credits to Uwe Dannowski and Heikki Vatiainen");
-MODULE_DESCRIPTION("FORE Systems 200E-series ATM driver - version " FORE200E_VERSION);
-
-static const int fore200e_rx_buf_nbr[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
-    { BUFFER_S1_NBR, BUFFER_L1_NBR },
-    { BUFFER_S2_NBR, BUFFER_L2_NBR }
-};
-
-static const int fore200e_rx_buf_size[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ] = {
-    { BUFFER_S1_SIZE, BUFFER_L1_SIZE },
-    { BUFFER_S2_SIZE, BUFFER_L2_SIZE }
-};
-
-
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG > 0)
-static const char* fore200e_traffic_class[] = { "NONE", "UBR", "CBR", "VBR", "ABR", "ANY" };
-#endif
-
-
-#if 0 /* currently unused */
-static int 
-fore200e_fore2atm_aal(enum fore200e_aal aal)
-{
-    switch(aal) {
-    case FORE200E_AAL0:  return ATM_AAL0;
-    case FORE200E_AAL34: return ATM_AAL34;
-    case FORE200E_AAL5:  return ATM_AAL5;
-    }
-
-    return -EINVAL;
-}
-#endif
-
-
-static enum fore200e_aal
-fore200e_atm2fore_aal(int aal)
-{
-    switch(aal) {
-    case ATM_AAL0:  return FORE200E_AAL0;
-    case ATM_AAL34: return FORE200E_AAL34;
-    case ATM_AAL1:
-    case ATM_AAL2:
-    case ATM_AAL5:  return FORE200E_AAL5;
-    }
-
-    return -EINVAL;
-}
-
-
-static char*
-fore200e_irq_itoa(int irq)
-{
-    static char str[8];
-    sprintf(str, "%d", irq);
-    return str;
-}
-
-
-/* allocate and align a chunk of memory intended to hold the data behing exchanged
-   between the driver and the adapter (using streaming DVMA) */
-
-static int
-fore200e_chunk_alloc(struct fore200e* fore200e, struct chunk* chunk, int size, int alignment, int direction)
-{
-    unsigned long offset = 0;
-
-    if (alignment <= sizeof(int))
-	alignment = 0;
-
-    chunk->alloc_size = size + alignment;
-    chunk->direction  = direction;
-
-    chunk->alloc_addr = kzalloc(chunk->alloc_size, GFP_KERNEL);
-    if (chunk->alloc_addr == NULL)
-	return -ENOMEM;
-
-    if (alignment > 0)
-	offset = FORE200E_ALIGN(chunk->alloc_addr, alignment); 
-    
-    chunk->align_addr = chunk->alloc_addr + offset;
-
-    chunk->dma_addr = dma_map_single(fore200e->dev, chunk->align_addr,
-				     size, direction);
-    if (dma_mapping_error(fore200e->dev, chunk->dma_addr)) {
-	kfree(chunk->alloc_addr);
-	return -ENOMEM;
-    }
-    return 0;
-}
-
-
-/* free a chunk of memory */
-
-static void
-fore200e_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
-{
-    dma_unmap_single(fore200e->dev, chunk->dma_addr, chunk->dma_size,
-		     chunk->direction);
-    kfree(chunk->alloc_addr);
-}
-
-/*
- * Allocate a DMA consistent chunk of memory intended to act as a communication
- * mechanism (to hold descriptors, status, queues, etc.) shared by the driver
- * and the adapter.
- */
-static int
-fore200e_dma_chunk_alloc(struct fore200e *fore200e, struct chunk *chunk,
-		int size, int nbr, int alignment)
-{
-	/* returned chunks are page-aligned */
-	chunk->alloc_size = size * nbr;
-	chunk->alloc_addr = dma_alloc_coherent(fore200e->dev, chunk->alloc_size,
-					       &chunk->dma_addr, GFP_KERNEL);
-	if (!chunk->alloc_addr)
-		return -ENOMEM;
-	chunk->align_addr = chunk->alloc_addr;
-	return 0;
-}
-
-/*
- * Free a DMA consistent chunk of memory.
- */
-static void
-fore200e_dma_chunk_free(struct fore200e* fore200e, struct chunk* chunk)
-{
-	dma_free_coherent(fore200e->dev, chunk->alloc_size, chunk->alloc_addr,
-			  chunk->dma_addr);
-}
-
-static void
-fore200e_spin(int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    while (time_before(jiffies, timeout));
-}
-
-
-static int
-fore200e_poll(struct fore200e* fore200e, volatile u32* addr, u32 val, int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    int           ok;
-
-    mb();
-    do {
-	if ((ok = (*addr == val)) || (*addr & STATUS_ERROR))
-	    break;
-
-    } while (time_before(jiffies, timeout));
-
-#if 1
-    if (!ok) {
-	printk(FORE200E "cmd polling failed, got status 0x%08x, expected 0x%08x\n",
-	       *addr, val);
-    }
-#endif
-
-    return ok;
-}
-
-
-static int
-fore200e_io_poll(struct fore200e* fore200e, volatile u32 __iomem *addr, u32 val, int msecs)
-{
-    unsigned long timeout = jiffies + msecs_to_jiffies(msecs);
-    int           ok;
-
-    do {
-	if ((ok = (fore200e->bus->read(addr) == val)))
-	    break;
-
-    } while (time_before(jiffies, timeout));
-
-#if 1
-    if (!ok) {
-	printk(FORE200E "I/O polling failed, got status 0x%08x, expected 0x%08x\n",
-	       fore200e->bus->read(addr), val);
-    }
-#endif
-
-    return ok;
-}
-
-
-static void
-fore200e_free_rx_buf(struct fore200e* fore200e)
-{
-    int scheme, magn, nbr;
-    struct buffer* buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    if ((buffer = fore200e->host_bsq[ scheme ][ magn ].buffer) != NULL) {
-
-		for (nbr = 0; nbr < fore200e_rx_buf_nbr[ scheme ][ magn ]; nbr++) {
-
-		    struct chunk* data = &buffer[ nbr ].data;
-
-		    if (data->alloc_addr != NULL)
-			fore200e_chunk_free(fore200e, data);
-		}
-	    }
-	}
-    }
-}
-
-
-static void
-fore200e_uninit_bs_queue(struct fore200e* fore200e)
-{
-    int scheme, magn;
-    
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    struct chunk* status    = &fore200e->host_bsq[ scheme ][ magn ].status;
-	    struct chunk* rbd_block = &fore200e->host_bsq[ scheme ][ magn ].rbd_block;
-	    
-	    if (status->alloc_addr)
-		fore200e_dma_chunk_free(fore200e, status);
-	    
-	    if (rbd_block->alloc_addr)
-		fore200e_dma_chunk_free(fore200e, rbd_block);
-	}
-    }
-}
-
-
-static int
-fore200e_reset(struct fore200e* fore200e, int diag)
-{
-    int ok;
-
-    fore200e->cp_monitor = fore200e->virt_base + FORE200E_CP_MONITOR_OFFSET;
-    
-    fore200e->bus->write(BSTAT_COLD_START, &fore200e->cp_monitor->bstat);
-
-    fore200e->bus->reset(fore200e);
-
-    if (diag) {
-	ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_SELFTEST_OK, 1000);
-	if (ok == 0) {
-	    
-	    printk(FORE200E "device %s self-test failed\n", fore200e->name);
-	    return -ENODEV;
-	}
-
-	printk(FORE200E "device %s self-test passed\n", fore200e->name);
-	
-	fore200e->state = FORE200E_STATE_RESET;
-    }
-
-    return 0;
-}
-
-
-static void
-fore200e_shutdown(struct fore200e* fore200e)
-{
-    printk(FORE200E "removing device %s at 0x%lx, IRQ %s\n",
-	   fore200e->name, fore200e->phys_base, 
-	   fore200e_irq_itoa(fore200e->irq));
-    
-    if (fore200e->state > FORE200E_STATE_RESET) {
-	/* first, reset the board to prevent further interrupts or data transfers */
-	fore200e_reset(fore200e, 0);
-    }
-    
-    /* then, release all allocated resources */
-    switch(fore200e->state) {
-
-    case FORE200E_STATE_COMPLETE:
-	kfree(fore200e->stats);
-
-	fallthrough;
-    case FORE200E_STATE_IRQ:
-	free_irq(fore200e->irq, fore200e->atm_dev);
-#ifdef FORE200E_USE_TASKLET
-	tasklet_kill(&fore200e->tx_tasklet);
-	tasklet_kill(&fore200e->rx_tasklet);
-#endif
-
-	fallthrough;
-    case FORE200E_STATE_ALLOC_BUF:
-	fore200e_free_rx_buf(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_BSQ:
-	fore200e_uninit_bs_queue(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_RXQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.status);
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_rxq.rpd);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_TXQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.status);
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_txq.tpd);
-
-	fallthrough;
-    case FORE200E_STATE_INIT_CMDQ:
-	fore200e_dma_chunk_free(fore200e, &fore200e->host_cmdq.status);
-
-	fallthrough;
-    case FORE200E_STATE_INITIALIZE:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_START_FW:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_RESET:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_MAP:
-	fore200e->bus->unmap(fore200e);
-
-	fallthrough;
-    case FORE200E_STATE_CONFIGURE:
-	/* nothing to do for that state */
-
-    case FORE200E_STATE_REGISTER:
-	/* XXX shouldn't we *start* by deregistering the device? */
-	atm_dev_deregister(fore200e->atm_dev);
-
-	fallthrough;
-    case FORE200E_STATE_BLANK:
-	/* nothing to do for that state */
-	break;
-    }
-}
-
-
-#ifdef CONFIG_PCI
-
-static u32 fore200e_pca_read(volatile u32 __iomem *addr)
-{
-    /* on big-endian hosts, the board is configured to convert
-       the endianess of slave RAM accesses  */
-    return le32_to_cpu(readl(addr));
-}
-
-
-static void fore200e_pca_write(u32 val, volatile u32 __iomem *addr)
-{
-    /* on big-endian hosts, the board is configured to convert
-       the endianess of slave RAM accesses  */
-    writel(cpu_to_le32(val), addr);
-}
-
-static int
-fore200e_pca_irq_check(struct fore200e* fore200e)
-{
-    /* this is a 1 bit register */
-    int irq_posted = readl(fore200e->regs.pca.psr);
-
-#if defined(CONFIG_ATM_FORE200E_DEBUG) && (CONFIG_ATM_FORE200E_DEBUG == 2)
-    if (irq_posted && (readl(fore200e->regs.pca.hcr) & PCA200E_HCR_OUTFULL)) {
-	DPRINTK(2,"FIFO OUT full, device %d\n", fore200e->atm_dev->number);
-    }
-#endif
-
-    return irq_posted;
-}
-
-
-static void
-fore200e_pca_irq_ack(struct fore200e* fore200e)
-{
-    writel(PCA200E_HCR_CLRINTR, fore200e->regs.pca.hcr);
-}
-
-
-static void
-fore200e_pca_reset(struct fore200e* fore200e)
-{
-    writel(PCA200E_HCR_RESET, fore200e->regs.pca.hcr);
-    fore200e_spin(10);
-    writel(0, fore200e->regs.pca.hcr);
-}
-
-
-static int fore200e_pca_map(struct fore200e* fore200e)
-{
-    DPRINTK(2, "device %s being mapped in memory\n", fore200e->name);
-
-    fore200e->virt_base = ioremap(fore200e->phys_base, PCA200E_IOSPACE_LENGTH);
-    
-    if (fore200e->virt_base == NULL) {
-	printk(FORE200E "can't map device %s\n", fore200e->name);
-	return -EFAULT;
-    }
-
-    DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
-
-    /* gain access to the PCA specific registers  */
-    fore200e->regs.pca.hcr = fore200e->virt_base + PCA200E_HCR_OFFSET;
-    fore200e->regs.pca.imr = fore200e->virt_base + PCA200E_IMR_OFFSET;
-    fore200e->regs.pca.psr = fore200e->virt_base + PCA200E_PSR_OFFSET;
-
-    fore200e->state = FORE200E_STATE_MAP;
-    return 0;
-}
-
-
-static void
-fore200e_pca_unmap(struct fore200e* fore200e)
-{
-    DPRINTK(2, "device %s being unmapped from memory\n", fore200e->name);
-
-    if (fore200e->virt_base != NULL)
-	iounmap(fore200e->virt_base);
-}
-
-
-static int fore200e_pca_configure(struct fore200e *fore200e)
-{
-    struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
-    u8              master_ctrl, latency;
-
-    DPRINTK(2, "device %s being configured\n", fore200e->name);
-
-    if ((pci_dev->irq == 0) || (pci_dev->irq == 0xFF)) {
-	printk(FORE200E "incorrect IRQ setting - misconfigured PCI-PCI bridge?\n");
-	return -EIO;
-    }
-
-    pci_read_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, &master_ctrl);
-
-    master_ctrl = master_ctrl
-#if defined(__BIG_ENDIAN)
-	/* request the PCA board to convert the endianess of slave RAM accesses */
-	| PCA200E_CTRL_CONVERT_ENDIAN
-#endif
-#if 0
-        | PCA200E_CTRL_DIS_CACHE_RD
-        | PCA200E_CTRL_DIS_WRT_INVAL
-        | PCA200E_CTRL_ENA_CONT_REQ_MODE
-        | PCA200E_CTRL_2_CACHE_WRT_INVAL
-#endif
-	| PCA200E_CTRL_LARGE_PCI_BURSTS;
-    
-    pci_write_config_byte(pci_dev, PCA200E_PCI_MASTER_CTRL, master_ctrl);
-
-    /* raise latency from 32 (default) to 192, as this seems to prevent NIC
-       lockups (under heavy rx loads) due to continuous 'FIFO OUT full' condition.
-       this may impact the performances of other PCI devices on the same bus, though */
-    latency = 192;
-    pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
-
-    fore200e->state = FORE200E_STATE_CONFIGURE;
-    return 0;
-}
-
-
-static int __init
-fore200e_pca_prom_read(struct fore200e* fore200e, struct prom_data* prom)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct prom_opcode      opcode;
-    int                     ok;
-    u32                     prom_dma;
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_PROM;
-    opcode.pad    = 0;
-
-    prom_dma = dma_map_single(fore200e->dev, prom, sizeof(struct prom_data),
-			      DMA_FROM_DEVICE);
-    if (dma_mapping_error(fore200e->dev, prom_dma))
-	return -ENOMEM;
-
-    fore200e->bus->write(prom_dma, &entry->cp_entry->cmd.prom_block.prom_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.prom_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    dma_unmap_single(fore200e->dev, prom_dma, sizeof(struct prom_data), DMA_FROM_DEVICE);
-
-    if (ok == 0) {
-	printk(FORE200E "unable to get PROM data from device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-#if defined(__BIG_ENDIAN)
-    
-#define swap_here(addr) (*((u32*)(addr)) = swab32( *((u32*)(addr)) ))
-
-    /* MAC address is stored as little-endian */
-    swap_here(&prom->mac_addr[0]);
-    swap_here(&prom->mac_addr[4]);
-#endif
-    
-    return 0;
-}
-
-
-static int
-fore200e_pca_proc_read(struct fore200e* fore200e, char *page)
-{
-    struct pci_dev *pci_dev = to_pci_dev(fore200e->dev);
-
-    return sprintf(page, "   PCI bus/slot/function:\t%d/%d/%d\n",
-		   pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn));
-}
-
-static const struct fore200e_bus fore200e_pci_ops = {
-	.model_name		= "PCA-200E",
-	.proc_name		= "pca200e",
-	.descr_alignment	= 32,
-	.buffer_alignment	= 4,
-	.status_alignment	= 32,
-	.read			= fore200e_pca_read,
-	.write			= fore200e_pca_write,
-	.configure		= fore200e_pca_configure,
-	.map			= fore200e_pca_map,
-	.reset			= fore200e_pca_reset,
-	.prom_read		= fore200e_pca_prom_read,
-	.unmap			= fore200e_pca_unmap,
-	.irq_check		= fore200e_pca_irq_check,
-	.irq_ack		= fore200e_pca_irq_ack,
-	.proc_read		= fore200e_pca_proc_read,
-};
-#endif /* CONFIG_PCI */
-
-#ifdef CONFIG_SBUS
-
-static u32 fore200e_sba_read(volatile u32 __iomem *addr)
-{
-    return sbus_readl(addr);
-}
-
-static void fore200e_sba_write(u32 val, volatile u32 __iomem *addr)
-{
-    sbus_writel(val, addr);
-}
-
-static void fore200e_sba_irq_enable(struct fore200e *fore200e)
-{
-	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-	fore200e->bus->write(hcr | SBA200E_HCR_INTR_ENA, fore200e->regs.sba.hcr);
-}
-
-static int fore200e_sba_irq_check(struct fore200e *fore200e)
-{
-	return fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_INTR_REQ;
-}
-
-static void fore200e_sba_irq_ack(struct fore200e *fore200e)
-{
-	u32 hcr = fore200e->bus->read(fore200e->regs.sba.hcr) & SBA200E_HCR_STICKY;
-	fore200e->bus->write(hcr | SBA200E_HCR_INTR_CLR, fore200e->regs.sba.hcr);
-}
-
-static void fore200e_sba_reset(struct fore200e *fore200e)
-{
-	fore200e->bus->write(SBA200E_HCR_RESET, fore200e->regs.sba.hcr);
-	fore200e_spin(10);
-	fore200e->bus->write(0, fore200e->regs.sba.hcr);
-}
-
-static int __init fore200e_sba_map(struct fore200e *fore200e)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	unsigned int bursts;
-
-	/* gain access to the SBA specific registers  */
-	fore200e->regs.sba.hcr = of_ioremap(&op->resource[0], 0, SBA200E_HCR_LENGTH, "SBA HCR");
-	fore200e->regs.sba.bsr = of_ioremap(&op->resource[1], 0, SBA200E_BSR_LENGTH, "SBA BSR");
-	fore200e->regs.sba.isr = of_ioremap(&op->resource[2], 0, SBA200E_ISR_LENGTH, "SBA ISR");
-	fore200e->virt_base    = of_ioremap(&op->resource[3], 0, SBA200E_RAM_LENGTH, "SBA RAM");
-
-	if (!fore200e->virt_base) {
-		printk(FORE200E "unable to map RAM of device %s\n", fore200e->name);
-		return -EFAULT;
-	}
-
-	DPRINTK(1, "device %s mapped to 0x%p\n", fore200e->name, fore200e->virt_base);
-    
-	fore200e->bus->write(0x02, fore200e->regs.sba.isr); /* XXX hardwired interrupt level */
-
-	/* get the supported DVMA burst sizes */
-	bursts = of_getintprop_default(op->dev.of_node->parent, "burst-sizes", 0x00);
-
-	if (sbus_can_dma_64bit())
-		sbus_set_sbus64(&op->dev, bursts);
-
-	fore200e->state = FORE200E_STATE_MAP;
-	return 0;
-}
-
-static void fore200e_sba_unmap(struct fore200e *fore200e)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-
-	of_iounmap(&op->resource[0], fore200e->regs.sba.hcr, SBA200E_HCR_LENGTH);
-	of_iounmap(&op->resource[1], fore200e->regs.sba.bsr, SBA200E_BSR_LENGTH);
-	of_iounmap(&op->resource[2], fore200e->regs.sba.isr, SBA200E_ISR_LENGTH);
-	of_iounmap(&op->resource[3], fore200e->virt_base,    SBA200E_RAM_LENGTH);
-}
-
-static int __init fore200e_sba_configure(struct fore200e *fore200e)
-{
-	fore200e->state = FORE200E_STATE_CONFIGURE;
-	return 0;
-}
-
-static int __init fore200e_sba_prom_read(struct fore200e *fore200e, struct prom_data *prom)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	const u8 *prop;
-	int len;
-
-	prop = of_get_property(op->dev.of_node, "madaddrlo2", &len);
-	if (!prop)
-		return -ENODEV;
-	memcpy(&prom->mac_addr[4], prop, 4);
-
-	prop = of_get_property(op->dev.of_node, "madaddrhi4", &len);
-	if (!prop)
-		return -ENODEV;
-	memcpy(&prom->mac_addr[2], prop, 4);
-
-	prom->serial_number = of_getintprop_default(op->dev.of_node,
-						    "serialnumber", 0);
-	prom->hw_revision = of_getintprop_default(op->dev.of_node,
-						  "promversion", 0);
-    
-	return 0;
-}
-
-static int fore200e_sba_proc_read(struct fore200e *fore200e, char *page)
-{
-	struct platform_device *op = to_platform_device(fore200e->dev);
-	const struct linux_prom_registers *regs;
-
-	regs = of_get_property(op->dev.of_node, "reg", NULL);
-
-	return sprintf(page, "   SBUS slot/device:\t\t%d/'%pOFn'\n",
-		       (regs ? regs->which_io : 0), op->dev.of_node);
-}
-
-static const struct fore200e_bus fore200e_sbus_ops = {
-	.model_name		= "SBA-200E",
-	.proc_name		= "sba200e",
-	.descr_alignment	= 32,
-	.buffer_alignment	= 64,
-	.status_alignment	= 32,
-	.read			= fore200e_sba_read,
-	.write			= fore200e_sba_write,
-	.configure		= fore200e_sba_configure,
-	.map			= fore200e_sba_map,
-	.reset			= fore200e_sba_reset,
-	.prom_read		= fore200e_sba_prom_read,
-	.unmap			= fore200e_sba_unmap,
-	.irq_enable		= fore200e_sba_irq_enable,
-	.irq_check		= fore200e_sba_irq_check,
-	.irq_ack		= fore200e_sba_irq_ack,
-	.proc_read		= fore200e_sba_proc_read,
-};
-#endif /* CONFIG_SBUS */
-
-static void
-fore200e_tx_irq(struct fore200e* fore200e)
-{
-    struct host_txq*        txq = &fore200e->host_txq;
-    struct host_txq_entry*  entry;
-    struct atm_vcc*         vcc;
-    struct fore200e_vc_map* vc_map;
-
-    if (fore200e->host_txq.txing == 0)
-	return;
-
-    for (;;) {
-	
-	entry = &txq->host_entry[ txq->tail ];
-
-        if ((*entry->status & STATUS_COMPLETE) == 0) {
-	    break;
-	}
-
-	DPRINTK(3, "TX COMPLETED: entry = %p [tail = %d], vc_map = %p, skb = %p\n", 
-		entry, txq->tail, entry->vc_map, entry->skb);
-
-	/* free copy of misaligned data */
-	kfree(entry->data);
-	
-	/* remove DMA mapping */
-	dma_unmap_single(fore200e->dev, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length,
-				 DMA_TO_DEVICE);
-
-	vc_map = entry->vc_map;
-
-	/* vcc closed since the time the entry was submitted for tx? */
-	if ((vc_map->vcc == NULL) ||
-	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
-
-	    DPRINTK(1, "no ready vcc found for PDU sent on device %d\n",
-		    fore200e->atm_dev->number);
-
-	    dev_kfree_skb_any(entry->skb);
-	}
-	else {
-	    ASSERT(vc_map->vcc);
-
-	    /* vcc closed then immediately re-opened? */
-	    if (vc_map->incarn != entry->incarn) {
-
-		/* when a vcc is closed, some PDUs may be still pending in the tx queue.
-		   if the same vcc is immediately re-opened, those pending PDUs must
-		   not be popped after the completion of their emission, as they refer
-		   to the prior incarnation of that vcc. otherwise, sk_atm(vcc)->sk_wmem_alloc
-		   would be decremented by the size of the (unrelated) skb, possibly
-		   leading to a negative sk->sk_wmem_alloc count, ultimately freezing the vcc.
-		   we thus bind the tx entry to the current incarnation of the vcc
-		   when the entry is submitted for tx. When the tx later completes,
-		   if the incarnation number of the tx entry does not match the one
-		   of the vcc, then this implies that the vcc has been closed then re-opened.
-		   we thus just drop the skb here. */
-
-		DPRINTK(1, "vcc closed-then-re-opened; dropping PDU sent on device %d\n",
-			fore200e->atm_dev->number);
-
-		dev_kfree_skb_any(entry->skb);
-	    }
-	    else {
-		vcc = vc_map->vcc;
-		ASSERT(vcc);
-
-		/* notify tx completion */
-		if (vcc->pop) {
-		    vcc->pop(vcc, entry->skb);
-		}
-		else {
-		    dev_kfree_skb_any(entry->skb);
-		}
-
-		/* check error condition */
-		if (*entry->status & STATUS_ERROR)
-		    atomic_inc(&vcc->stats->tx_err);
-		else
-		    atomic_inc(&vcc->stats->tx);
-	    }
-	}
-
-	*entry->status = STATUS_FREE;
-
-	fore200e->host_txq.txing--;
-
-	FORE200E_NEXT_ENTRY(txq->tail, QUEUE_SIZE_TX);
-    }
-}
-
-
-#ifdef FORE200E_BSQ_DEBUG
-int bsq_audit(int where, struct host_bsq* bsq, int scheme, int magn)
-{
-    struct buffer* buffer;
-    int count = 0;
-
-    buffer = bsq->freebuf;
-    while (buffer) {
-
-	if (buffer->supplied) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld supplied but in free list!\n",
-		   where, scheme, magn, buffer->index);
-	}
-
-	if (buffer->magn != magn) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected magn = %d\n",
-		   where, scheme, magn, buffer->index, buffer->magn);
-	}
-
-	if (buffer->scheme != scheme) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, buffer %ld, unexpected scheme = %d\n",
-		   where, scheme, magn, buffer->index, buffer->scheme);
-	}
-
-	if ((buffer->index < 0) || (buffer->index >= fore200e_rx_buf_nbr[ scheme ][ magn ])) {
-	    printk(FORE200E "bsq_audit(%d): queue %d.%d, out of range buffer index = %ld !\n",
-		   where, scheme, magn, buffer->index);
-	}
-
-	count++;
-	buffer = buffer->next;
-    }
-
-    if (count != bsq->freebuf_count) {
-	printk(FORE200E "bsq_audit(%d): queue %d.%d, %d bufs in free list, but freebuf_count = %d\n",
-	       where, scheme, magn, count, bsq->freebuf_count);
-    }
-    return 0;
-}
-#endif
-
-
-static void
-fore200e_supply(struct fore200e* fore200e)
-{
-    int  scheme, magn, i;
-
-    struct host_bsq*       bsq;
-    struct host_bsq_entry* entry;
-    struct buffer*         buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-#ifdef FORE200E_BSQ_DEBUG
-	    bsq_audit(1, bsq, scheme, magn);
-#endif
-	    while (bsq->freebuf_count >= RBD_BLK_SIZE) {
-
-		DPRINTK(2, "supplying %d rx buffers to queue %d / %d, freebuf_count = %d\n",
-			RBD_BLK_SIZE, scheme, magn, bsq->freebuf_count);
-
-		entry = &bsq->host_entry[ bsq->head ];
-
-		for (i = 0; i < RBD_BLK_SIZE; i++) {
-
-		    /* take the first buffer in the free buffer list */
-		    buffer = bsq->freebuf;
-		    if (!buffer) {
-			printk(FORE200E "no more free bufs in queue %d.%d, but freebuf_count = %d\n",
-			       scheme, magn, bsq->freebuf_count);
-			return;
-		    }
-		    bsq->freebuf = buffer->next;
-		    
-#ifdef FORE200E_BSQ_DEBUG
-		    if (buffer->supplied)
-			printk(FORE200E "queue %d.%d, buffer %lu already supplied\n",
-			       scheme, magn, buffer->index);
-		    buffer->supplied = 1;
-#endif
-		    entry->rbd_block->rbd[ i ].buffer_haddr = buffer->data.dma_addr;
-		    entry->rbd_block->rbd[ i ].handle       = FORE200E_BUF2HDL(buffer);
-		}
-
-		FORE200E_NEXT_ENTRY(bsq->head, QUEUE_SIZE_BS);
-
- 		/* decrease accordingly the number of free rx buffers */
-		bsq->freebuf_count -= RBD_BLK_SIZE;
-
-		*entry->status = STATUS_PENDING;
-		fore200e->bus->write(entry->rbd_block_dma, &entry->cp_entry->rbd_block_haddr);
-	    }
-	}
-    }
-}
-
-
-static int
-fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rpd)
-{
-    struct sk_buff*      skb;
-    struct buffer*       buffer;
-    struct fore200e_vcc* fore200e_vcc;
-    int                  i, pdu_len = 0;
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    u32                  cell_header = 0;
-#endif
-
-    ASSERT(vcc);
-    
-    fore200e_vcc = FORE200E_VCC(vcc);
-    ASSERT(fore200e_vcc);
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.rxtp.max_sdu == ATM_AAL0_SDU)) {
-
-	cell_header = (rpd->atm_header.gfc << ATM_HDR_GFC_SHIFT) |
-	              (rpd->atm_header.vpi << ATM_HDR_VPI_SHIFT) |
-                      (rpd->atm_header.vci << ATM_HDR_VCI_SHIFT) |
-                      (rpd->atm_header.plt << ATM_HDR_PTI_SHIFT) | 
-                       rpd->atm_header.clp;
-	pdu_len = 4;
-    }
-#endif
-    
-    /* compute total PDU length */
-    for (i = 0; i < rpd->nseg; i++)
-	pdu_len += rpd->rsd[ i ].length;
-    
-    skb = alloc_skb(pdu_len, GFP_ATOMIC);
-    if (skb == NULL) {
-	DPRINTK(2, "unable to alloc new skb, rx PDU length = %d\n", pdu_len);
-
-	atomic_inc(&vcc->stats->rx_drop);
-	return -ENOMEM;
-    } 
-
-    __net_timestamp(skb);
-    
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if (cell_header) {
-	*((u32*)skb_put(skb, 4)) = cell_header;
-    }
-#endif
-
-    /* reassemble segments */
-    for (i = 0; i < rpd->nseg; i++) {
-	
-	/* rebuild rx buffer address from rsd handle */
-	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
-	
-	/* Make device DMA transfer visible to CPU.  */
-	dma_sync_single_for_cpu(fore200e->dev, buffer->data.dma_addr,
-				rpd->rsd[i].length, DMA_FROM_DEVICE);
-	
-	skb_put_data(skb, buffer->data.align_addr, rpd->rsd[i].length);
-
-	/* Now let the device get at it again.  */
-	dma_sync_single_for_device(fore200e->dev, buffer->data.dma_addr,
-				   rpd->rsd[i].length, DMA_FROM_DEVICE);
-    }
-
-    DPRINTK(3, "rx skb: len = %d, truesize = %d\n", skb->len, skb->truesize);
-    
-    if (pdu_len < fore200e_vcc->rx_min_pdu)
-	fore200e_vcc->rx_min_pdu = pdu_len;
-    if (pdu_len > fore200e_vcc->rx_max_pdu)
-	fore200e_vcc->rx_max_pdu = pdu_len;
-    fore200e_vcc->rx_pdu++;
-
-    /* push PDU */
-    if (atm_charge(vcc, skb->truesize) == 0) {
-
-	DPRINTK(2, "receive buffers saturated for %d.%d.%d - PDU dropped\n",
-		vcc->itf, vcc->vpi, vcc->vci);
-
-	dev_kfree_skb_any(skb);
-
-	atomic_inc(&vcc->stats->rx_drop);
-	return -ENOMEM;
-    }
-
-    vcc->push(vcc, skb);
-    atomic_inc(&vcc->stats->rx);
-
-    return 0;
-}
-
-
-static void
-fore200e_collect_rpd(struct fore200e* fore200e, struct rpd* rpd)
-{
-    struct host_bsq* bsq;
-    struct buffer*   buffer;
-    int              i;
-    
-    for (i = 0; i < rpd->nseg; i++) {
-
-	/* rebuild rx buffer address from rsd handle */
-	buffer = FORE200E_HDL2BUF(rpd->rsd[ i ].handle);
-
-	bsq = &fore200e->host_bsq[ buffer->scheme ][ buffer->magn ];
-
-#ifdef FORE200E_BSQ_DEBUG
-	bsq_audit(2, bsq, buffer->scheme, buffer->magn);
-
-	if (buffer->supplied == 0)
-	    printk(FORE200E "queue %d.%d, buffer %ld was not supplied\n",
-		   buffer->scheme, buffer->magn, buffer->index);
-	buffer->supplied = 0;
-#endif
-
-	/* re-insert the buffer into the free buffer list */
-	buffer->next = bsq->freebuf;
-	bsq->freebuf = buffer;
-
-	/* then increment the number of free rx buffers */
-	bsq->freebuf_count++;
-    }
-}
-
-
-static void
-fore200e_rx_irq(struct fore200e* fore200e)
-{
-    struct host_rxq*        rxq = &fore200e->host_rxq;
-    struct host_rxq_entry*  entry;
-    struct atm_vcc*         vcc;
-    struct fore200e_vc_map* vc_map;
-
-    for (;;) {
-	
-	entry = &rxq->host_entry[ rxq->head ];
-
-	/* no more received PDUs */
-	if ((*entry->status & STATUS_COMPLETE) == 0)
-	    break;
-
-	vc_map = FORE200E_VC_MAP(fore200e, entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-
-	if ((vc_map->vcc == NULL) ||
-	    (test_bit(ATM_VF_READY, &vc_map->vcc->flags) == 0)) {
-
-	    DPRINTK(1, "no ready VC found for PDU received on %d.%d.%d\n",
-		    fore200e->atm_dev->number,
-		    entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-	}
-	else {
-	    vcc = vc_map->vcc;
-	    ASSERT(vcc);
-
-	    if ((*entry->status & STATUS_ERROR) == 0) {
-
-		fore200e_push_rpd(fore200e, vcc, entry->rpd);
-	    }
-	    else {
-		DPRINTK(2, "damaged PDU on %d.%d.%d\n",
-			fore200e->atm_dev->number,
-			entry->rpd->atm_header.vpi, entry->rpd->atm_header.vci);
-		atomic_inc(&vcc->stats->rx_err);
-	    }
-	}
-
-	FORE200E_NEXT_ENTRY(rxq->head, QUEUE_SIZE_RX);
-
-	fore200e_collect_rpd(fore200e, entry->rpd);
-
-	/* rewrite the rpd address to ack the received PDU */
-	fore200e->bus->write(entry->rpd_dma, &entry->cp_entry->rpd_haddr);
-	*entry->status = STATUS_FREE;
-
-	fore200e_supply(fore200e);
-    }
-}
-
-
-#ifndef FORE200E_USE_TASKLET
-static void
-fore200e_irq(struct fore200e* fore200e)
-{
-    unsigned long flags;
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_rx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_tx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-#endif
-
-
-static irqreturn_t
-fore200e_interrupt(int irq, void* dev)
-{
-    struct fore200e* fore200e = FORE200E_DEV((struct atm_dev*)dev);
-
-    if (fore200e->bus->irq_check(fore200e) == 0) {
-	
-	DPRINTK(3, "interrupt NOT triggered by device %d\n", fore200e->atm_dev->number);
-	return IRQ_NONE;
-    }
-    DPRINTK(3, "interrupt triggered by device %d\n", fore200e->atm_dev->number);
-
-#ifdef FORE200E_USE_TASKLET
-    tasklet_schedule(&fore200e->tx_tasklet);
-    tasklet_schedule(&fore200e->rx_tasklet);
-#else
-    fore200e_irq(fore200e);
-#endif
-    
-    fore200e->bus->irq_ack(fore200e);
-    return IRQ_HANDLED;
-}
-
-
-#ifdef FORE200E_USE_TASKLET
-static void
-fore200e_tx_tasklet(unsigned long data)
-{
-    struct fore200e* fore200e = (struct fore200e*) data;
-    unsigned long flags;
-
-    DPRINTK(3, "tx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_tx_irq(fore200e);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-
-
-static void
-fore200e_rx_tasklet(unsigned long data)
-{
-    struct fore200e* fore200e = (struct fore200e*) data;
-    unsigned long    flags;
-
-    DPRINTK(3, "rx tasklet scheduled for device %d\n", fore200e->atm_dev->number);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-    fore200e_rx_irq((struct fore200e*) data);
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-}
-#endif
-
-
-static int
-fore200e_select_scheme(struct atm_vcc* vcc)
-{
-    /* fairly balance the VCs over (identical) buffer schemes */
-    int scheme = vcc->vci % 2 ? BUFFER_SCHEME_ONE : BUFFER_SCHEME_TWO;
-
-    DPRINTK(1, "VC %d.%d.%d uses buffer scheme %d\n",
-	    vcc->itf, vcc->vpi, vcc->vci, scheme);
-
-    return scheme;
-}
-
-
-static int 
-fore200e_activate_vcin(struct fore200e* fore200e, int activate, struct atm_vcc* vcc, int mtu)
-{
-    struct host_cmdq*        cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry*  entry = &cmdq->host_entry[ cmdq->head ];
-    struct activate_opcode   activ_opcode;
-    struct deactivate_opcode deactiv_opcode;
-    struct vpvc              vpvc;
-    int                      ok;
-    enum fore200e_aal        aal = fore200e_atm2fore_aal(vcc->qos.aal);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-    
-    if (activate) {
-	FORE200E_VCC(vcc)->scheme = fore200e_select_scheme(vcc);
-	
-	activ_opcode.opcode = OPCODE_ACTIVATE_VCIN;
-	activ_opcode.aal    = aal;
-	activ_opcode.scheme = FORE200E_VCC(vcc)->scheme;
-	activ_opcode.pad    = 0;
-    }
-    else {
-	deactiv_opcode.opcode = OPCODE_DEACTIVATE_VCIN;
-	deactiv_opcode.pad    = 0;
-    }
-
-    vpvc.vci = vcc->vci;
-    vpvc.vpi = vcc->vpi;
-
-    *entry->status = STATUS_PENDING;
-
-    if (activate) {
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-	mtu = 48;
-#endif
-	/* the MTU is not used by the cp, except in the case of AAL0 */
-	fore200e->bus->write(mtu,                        &entry->cp_entry->cmd.activate_block.mtu);
-	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.activate_block.vpvc);
-	fore200e->bus->write(*(u32*)&activ_opcode, (u32 __iomem *)&entry->cp_entry->cmd.activate_block.opcode);
-    }
-    else {
-	fore200e->bus->write(*(u32*)&vpvc,         (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.vpvc);
-	fore200e->bus->write(*(u32*)&deactiv_opcode, (u32 __iomem *)&entry->cp_entry->cmd.deactivate_block.opcode);
-    }
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    if (ok == 0) {
-	printk(FORE200E "unable to %s VC %d.%d.%d\n",
-	       activate ? "open" : "close", vcc->itf, vcc->vpi, vcc->vci);
-	return -EIO;
-    }
-
-    DPRINTK(1, "VC %d.%d.%d %sed\n", vcc->itf, vcc->vpi, vcc->vci, 
-	    activate ? "open" : "clos");
-
-    return 0;
-}
-
-
-#define FORE200E_MAX_BACK2BACK_CELLS 255    /* XXX depends on CDVT */
-
-static void
-fore200e_rate_ctrl(struct atm_qos* qos, struct tpd_rate* rate)
-{
-    if (qos->txtp.max_pcr < ATM_OC3_PCR) {
-    
-	/* compute the data cells to idle cells ratio from the tx PCR */
-	rate->data_cells = qos->txtp.max_pcr * FORE200E_MAX_BACK2BACK_CELLS / ATM_OC3_PCR;
-	rate->idle_cells = FORE200E_MAX_BACK2BACK_CELLS - rate->data_cells;
-    }
-    else {
-	/* disable rate control */
-	rate->data_cells = rate->idle_cells = 0;
-    }
-}
-
-
-static int
-fore200e_open(struct atm_vcc *vcc)
-{
-    struct fore200e*        fore200e = FORE200E_DEV(vcc->dev);
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e_vc_map* vc_map;
-    unsigned long	    flags;
-    int			    vci = vcc->vci;
-    short		    vpi = vcc->vpi;
-
-    ASSERT((vpi >= 0) && (vpi < 1<<FORE200E_VPI_BITS));
-    ASSERT((vci >= 0) && (vci < 1<<FORE200E_VCI_BITS));
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    vc_map = FORE200E_VC_MAP(fore200e, vpi, vci);
-    if (vc_map->vcc) {
-
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-	printk(FORE200E "VC %d.%d.%d already in use\n",
-	       fore200e->atm_dev->number, vpi, vci);
-
-	return -EINVAL;
-    }
-
-    vc_map->vcc = vcc;
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    fore200e_vcc = kzalloc_obj(struct fore200e_vcc, GFP_ATOMIC);
-    if (fore200e_vcc == NULL) {
-	vc_map->vcc = NULL;
-	return -ENOMEM;
-    }
-
-    DPRINTK(2, "opening %d.%d.%d:%d QoS = (tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
-	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d)\n",
-	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-	    fore200e_traffic_class[ vcc->qos.txtp.traffic_class ],
-	    vcc->qos.txtp.min_pcr, vcc->qos.txtp.max_pcr, vcc->qos.txtp.max_cdv, vcc->qos.txtp.max_sdu,
-	    fore200e_traffic_class[ vcc->qos.rxtp.traffic_class ],
-	    vcc->qos.rxtp.min_pcr, vcc->qos.rxtp.max_pcr, vcc->qos.rxtp.max_cdv, vcc->qos.rxtp.max_sdu);
-    
-    /* pseudo-CBR bandwidth requested? */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-	
-	mutex_lock(&fore200e->rate_mtx);
-	if (fore200e->available_cell_rate < vcc->qos.txtp.max_pcr) {
-	    mutex_unlock(&fore200e->rate_mtx);
-
-	    kfree(fore200e_vcc);
-	    vc_map->vcc = NULL;
-	    return -EAGAIN;
-	}
-
-	/* reserve bandwidth */
-	fore200e->available_cell_rate -= vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-    }
-    
-    vcc->itf = vcc->dev->number;
-
-    set_bit(ATM_VF_PARTIAL,&vcc->flags);
-    set_bit(ATM_VF_ADDR, &vcc->flags);
-
-    vcc->dev_data = fore200e_vcc;
-    
-    if (fore200e_activate_vcin(fore200e, 1, vcc, vcc->qos.rxtp.max_sdu) < 0) {
-
-	vc_map->vcc = NULL;
-
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-	clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-
-	vcc->dev_data = NULL;
-
-	mutex_lock(&fore200e->rate_mtx);
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-
-	kfree(fore200e_vcc);
-	return -EINVAL;
-    }
-    
-    /* compute rate control parameters */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-	
-	fore200e_rate_ctrl(&vcc->qos, &fore200e_vcc->rate);
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-	DPRINTK(3, "tx on %d.%d.%d:%d, tx PCR = %d, rx PCR = %d, data_cells = %u, idle_cells = %u\n",
-		vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-		vcc->qos.txtp.max_pcr, vcc->qos.rxtp.max_pcr, 
-		fore200e_vcc->rate.data_cells, fore200e_vcc->rate.idle_cells);
-    }
-    
-    fore200e_vcc->tx_min_pdu = fore200e_vcc->rx_min_pdu = MAX_PDU_SIZE + 1;
-    fore200e_vcc->tx_max_pdu = fore200e_vcc->rx_max_pdu = 0;
-    fore200e_vcc->tx_pdu     = fore200e_vcc->rx_pdu     = 0;
-
-    /* new incarnation of the vcc */
-    vc_map->incarn = ++fore200e->incarn_count;
-
-    /* VC unusable before this flag is set */
-    set_bit(ATM_VF_READY, &vcc->flags);
-
-    return 0;
-}
-
-
-static void
-fore200e_close(struct atm_vcc* vcc)
-{
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e*        fore200e;
-    struct fore200e_vc_map* vc_map;
-    unsigned long           flags;
-
-    ASSERT(vcc);
-    fore200e = FORE200E_DEV(vcc->dev);
-
-    ASSERT((vcc->vpi >= 0) && (vcc->vpi < 1<<FORE200E_VPI_BITS));
-    ASSERT((vcc->vci >= 0) && (vcc->vci < 1<<FORE200E_VCI_BITS));
-
-    DPRINTK(2, "closing %d.%d.%d:%d\n", vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal));
-
-    clear_bit(ATM_VF_READY, &vcc->flags);
-
-    fore200e_activate_vcin(fore200e, 0, vcc, 0);
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
-
-    /* the vc is no longer considered as "in use" by fore200e_open() */
-    vc_map->vcc = NULL;
-
-    vcc->itf = vcc->vci = vcc->vpi = 0;
-
-    fore200e_vcc = FORE200E_VCC(vcc);
-    vcc->dev_data = NULL;
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    /* release reserved bandwidth, if any */
-    if ((vcc->qos.txtp.traffic_class == ATM_CBR) && (vcc->qos.txtp.max_pcr > 0)) {
-
-	mutex_lock(&fore200e->rate_mtx);
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	mutex_unlock(&fore200e->rate_mtx);
-
-	clear_bit(ATM_VF_HASQOS, &vcc->flags);
-    }
-
-    clear_bit(ATM_VF_ADDR, &vcc->flags);
-    clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-
-    ASSERT(fore200e_vcc);
-    kfree(fore200e_vcc);
-}
-
-
-static int
-fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-    struct fore200e*        fore200e;
-    struct fore200e_vcc*    fore200e_vcc;
-    struct fore200e_vc_map* vc_map;
-    struct host_txq*        txq;
-    struct host_txq_entry*  entry;
-    struct tpd*             tpd;
-    struct tpd_haddr        tpd_haddr;
-    int                     retry        = CONFIG_ATM_FORE200E_TX_RETRY;
-    int                     tx_copy      = 0;
-    int                     tx_len       = skb->len;
-    u32*                    cell_header  = NULL;
-    unsigned char*          skb_data;
-    int                     skb_len;
-    unsigned char*          data;
-    unsigned long           flags;
-
-    if (!vcc)
-        return -EINVAL;
-
-    fore200e = FORE200E_DEV(vcc->dev);
-    fore200e_vcc = FORE200E_VCC(vcc);
-
-    if (!fore200e)
-        return -EINVAL;
-
-    txq = &fore200e->host_txq;
-    if (!fore200e_vcc)
-        return -EINVAL;
-
-    if (!test_bit(ATM_VF_READY, &vcc->flags)) {
-	DPRINTK(1, "VC %d.%d.%d not ready for tx\n", vcc->itf, vcc->vpi, vcc->vpi);
-	dev_kfree_skb_any(skb);
-	return -EINVAL;
-    }
-
-#ifdef FORE200E_52BYTE_AAL0_SDU
-    if ((vcc->qos.aal == ATM_AAL0) && (vcc->qos.txtp.max_sdu == ATM_AAL0_SDU)) {
-	cell_header = (u32*) skb->data;
-	skb_data    = skb->data + 4;    /* skip 4-byte cell header */
-	skb_len     = tx_len = skb->len  - 4;
-
-	DPRINTK(3, "user-supplied cell header = 0x%08x\n", *cell_header);
-    }
-    else 
-#endif
-    {
-	skb_data = skb->data;
-	skb_len  = skb->len;
-    }
-    
-    if (((unsigned long)skb_data) & 0x3) {
-
-	DPRINTK(2, "misaligned tx PDU on device %s\n", fore200e->name);
-	tx_copy = 1;
-	tx_len  = skb_len;
-    }
-
-    if ((vcc->qos.aal == ATM_AAL0) && (skb_len % ATM_CELL_PAYLOAD)) {
-
-        /* this simply NUKES the PCA board */
-	DPRINTK(2, "incomplete tx AAL0 PDU on device %s\n", fore200e->name);
-	tx_copy = 1;
-	tx_len  = ((skb_len / ATM_CELL_PAYLOAD) + 1) * ATM_CELL_PAYLOAD;
-    }
-    
-    if (tx_copy) {
-	data = kmalloc(tx_len, GFP_ATOMIC);
-	if (data == NULL) {
-	    if (vcc->pop) {
-		vcc->pop(vcc, skb);
-	    }
-	    else {
-		dev_kfree_skb_any(skb);
-	    }
-	    return -ENOMEM;
-	}
-
-	memcpy(data, skb_data, skb_len);
-	if (skb_len < tx_len)
-	    memset(data + skb_len, 0x00, tx_len - skb_len);
-    }
-    else {
-	data = skb_data;
-    }
-
-    vc_map = FORE200E_VC_MAP(fore200e, vcc->vpi, vcc->vci);
-    ASSERT(vc_map->vcc == vcc);
-
-  retry_here:
-
-    spin_lock_irqsave(&fore200e->q_lock, flags);
-
-    entry = &txq->host_entry[ txq->head ];
-
-    if ((*entry->status != STATUS_FREE) || (txq->txing >= QUEUE_SIZE_TX - 2)) {
-
-	/* try to free completed tx queue entries */
-	fore200e_tx_irq(fore200e);
-
-	if (*entry->status != STATUS_FREE) {
-
-	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-	    /* retry once again? */
-	    if (--retry > 0) {
-		udelay(50);
-		goto retry_here;
-	    }
-
-	    atomic_inc(&vcc->stats->tx_err);
-
-	    fore200e->tx_sat++;
-	    DPRINTK(2, "tx queue of device %s is saturated, PDU dropped - heartbeat is %08x\n",
-		    fore200e->name, fore200e->cp_queues->heartbeat);
-	    if (vcc->pop) {
-		vcc->pop(vcc, skb);
-	    }
-	    else {
-		dev_kfree_skb_any(skb);
-	    }
-
-	    if (tx_copy)
-		kfree(data);
-
-	    return -ENOBUFS;
-	}
-    }
-
-    entry->incarn = vc_map->incarn;
-    entry->vc_map = vc_map;
-    entry->skb    = skb;
-    entry->data   = tx_copy ? data : NULL;
-
-    tpd = entry->tpd;
-    tpd->tsd[ 0 ].buffer = dma_map_single(fore200e->dev, data, tx_len,
-					  DMA_TO_DEVICE);
-    if (dma_mapping_error(fore200e->dev, tpd->tsd[0].buffer)) {
-	if (tx_copy)
-	    kfree(data);
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-	return -ENOMEM;
-    }
-    tpd->tsd[ 0 ].length = tx_len;
-
-    FORE200E_NEXT_ENTRY(txq->head, QUEUE_SIZE_TX);
-    txq->txing++;
-
-    /* The dma_map call above implies a dma_sync so the device can use it,
-     * thus no explicit dma_sync call is necessary here.
-     */
-    
-    DPRINTK(3, "tx on %d.%d.%d:%d, len = %u (%u)\n", 
-	    vcc->itf, vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-	    tpd->tsd[0].length, skb_len);
-
-    if (skb_len < fore200e_vcc->tx_min_pdu)
-	fore200e_vcc->tx_min_pdu = skb_len;
-    if (skb_len > fore200e_vcc->tx_max_pdu)
-	fore200e_vcc->tx_max_pdu = skb_len;
-    fore200e_vcc->tx_pdu++;
-
-    /* set tx rate control information */
-    tpd->rate.data_cells = fore200e_vcc->rate.data_cells;
-    tpd->rate.idle_cells = fore200e_vcc->rate.idle_cells;
-
-    if (cell_header) {
-	tpd->atm_header.clp = (*cell_header & ATM_HDR_CLP);
-	tpd->atm_header.plt = (*cell_header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
-	tpd->atm_header.vci = (*cell_header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
-	tpd->atm_header.vpi = (*cell_header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
-	tpd->atm_header.gfc = (*cell_header & ATM_HDR_GFC_MASK) >> ATM_HDR_GFC_SHIFT;
-    }
-    else {
-	/* set the ATM header, common to all cells conveying the PDU */
-	tpd->atm_header.clp = 0;
-	tpd->atm_header.plt = 0;
-	tpd->atm_header.vci = vcc->vci;
-	tpd->atm_header.vpi = vcc->vpi;
-	tpd->atm_header.gfc = 0;
-    }
-
-    tpd->spec.length = tx_len;
-    tpd->spec.nseg   = 1;
-    tpd->spec.aal    = fore200e_atm2fore_aal(vcc->qos.aal);
-    tpd->spec.intr   = 1;
-
-    tpd_haddr.size  = sizeof(struct tpd) / (1<<TPD_HADDR_SHIFT);  /* size is expressed in 32 byte blocks */
-    tpd_haddr.pad   = 0;
-    tpd_haddr.haddr = entry->tpd_dma >> TPD_HADDR_SHIFT;          /* shift the address, as we are in a bitfield */
-
-    *entry->status = STATUS_PENDING;
-    fore200e->bus->write(*(u32*)&tpd_haddr, (u32 __iomem *)&entry->cp_entry->tpd_haddr);
-
-    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-
-    return 0;
-}
-
-
-static int
-fore200e_getstats(struct fore200e* fore200e)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct stats_opcode     opcode;
-    int                     ok;
-    u32                     stats_dma_addr;
-
-    if (fore200e->stats == NULL) {
-	fore200e->stats = kzalloc_obj(struct stats);
-	if (fore200e->stats == NULL)
-	    return -ENOMEM;
-    }
-    
-    stats_dma_addr = dma_map_single(fore200e->dev, fore200e->stats,
-				    sizeof(struct stats), DMA_FROM_DEVICE);
-    if (dma_mapping_error(fore200e->dev, stats_dma_addr))
-    	return -ENOMEM;
-    
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_STATS;
-    opcode.pad    = 0;
-
-    fore200e->bus->write(stats_dma_addr, &entry->cp_entry->cmd.stats_block.stats_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.stats_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    dma_unmap_single(fore200e->dev, stats_dma_addr, sizeof(struct stats), DMA_FROM_DEVICE);
-    
-    if (ok == 0) {
-	printk(FORE200E "unable to get statistics from device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-
-#if 0 /* currently unused */
-static int
-fore200e_get_oc3(struct fore200e* fore200e, struct oc3_regs* regs)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct oc3_opcode       opcode;
-    int                     ok;
-    u32                     oc3_regs_dma_addr;
-
-    oc3_regs_dma_addr = fore200e->bus->dma_map(fore200e, regs, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_GET_OC3;
-    opcode.reg    = 0;
-    opcode.value  = 0;
-    opcode.mask   = 0;
-
-    fore200e->bus->write(oc3_regs_dma_addr, &entry->cp_entry->cmd.oc3_block.regs_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32*)&entry->cp_entry->cmd.oc3_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    fore200e->bus->dma_unmap(fore200e, oc3_regs_dma_addr, sizeof(struct oc3_regs), DMA_FROM_DEVICE);
-    
-    if (ok == 0) {
-	printk(FORE200E "unable to get OC-3 regs of device %s\n", fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-#endif
-
-
-static int
-fore200e_set_oc3(struct fore200e* fore200e, u32 reg, u32 value, u32 mask)
-{
-    struct host_cmdq*       cmdq  = &fore200e->host_cmdq;
-    struct host_cmdq_entry* entry = &cmdq->host_entry[ cmdq->head ];
-    struct oc3_opcode       opcode;
-    int                     ok;
-
-    DPRINTK(2, "set OC-3 reg = 0x%02x, value = 0x%02x, mask = 0x%02x\n", reg, value, mask);
-
-    FORE200E_NEXT_ENTRY(cmdq->head, QUEUE_SIZE_CMD);
-
-    opcode.opcode = OPCODE_SET_OC3;
-    opcode.reg    = reg;
-    opcode.value  = value;
-    opcode.mask   = mask;
-
-    fore200e->bus->write(0, &entry->cp_entry->cmd.oc3_block.regs_haddr);
-    
-    *entry->status = STATUS_PENDING;
-
-    fore200e->bus->write(*(u32*)&opcode, (u32 __iomem *)&entry->cp_entry->cmd.oc3_block.opcode);
-
-    ok = fore200e_poll(fore200e, entry->status, STATUS_COMPLETE, 400);
-
-    *entry->status = STATUS_FREE;
-
-    if (ok == 0) {
-	printk(FORE200E "unable to set OC-3 reg 0x%02x of device %s\n", reg, fore200e->name);
-	return -EIO;
-    }
-
-    return 0;
-}
-
-
-static int
-fore200e_setloop(struct fore200e* fore200e, int loop_mode)
-{
-    u32 mct_value, mct_mask;
-    int error;
-
-    if (!capable(CAP_NET_ADMIN))
-	return -EPERM;
-    
-    switch (loop_mode) {
-
-    case ATM_LM_NONE:
-	mct_value = 0; 
-	mct_mask  = SUNI_MCT_DLE | SUNI_MCT_LLE;
-	break;
-	
-    case ATM_LM_LOC_PHY:
-	mct_value = mct_mask = SUNI_MCT_DLE;
-	break;
-
-    case ATM_LM_RMT_PHY:
-	mct_value = mct_mask = SUNI_MCT_LLE;
-	break;
-
-    default:
-	return -EINVAL;
-    }
-
-    error = fore200e_set_oc3(fore200e, SUNI_MCT, mct_value, mct_mask);
-    if (error == 0)
-	fore200e->loop_mode = loop_mode;
-
-    return error;
-}
-
-
-static int
-fore200e_fetch_stats(struct fore200e* fore200e, struct sonet_stats __user *arg)
-{
-    struct sonet_stats tmp;
-
-    if (fore200e_getstats(fore200e) < 0)
-	return -EIO;
-
-    tmp.section_bip = be32_to_cpu(fore200e->stats->oc3.section_bip8_errors);
-    tmp.line_bip    = be32_to_cpu(fore200e->stats->oc3.line_bip24_errors);
-    tmp.path_bip    = be32_to_cpu(fore200e->stats->oc3.path_bip8_errors);
-    tmp.line_febe   = be32_to_cpu(fore200e->stats->oc3.line_febe_errors);
-    tmp.path_febe   = be32_to_cpu(fore200e->stats->oc3.path_febe_errors);
-    tmp.corr_hcs    = be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors);
-    tmp.uncorr_hcs  = be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors);
-    tmp.tx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_transmitted)  +
-	              be32_to_cpu(fore200e->stats->aal34.cells_transmitted) +
-	              be32_to_cpu(fore200e->stats->aal5.cells_transmitted);
-    tmp.rx_cells    = be32_to_cpu(fore200e->stats->aal0.cells_received)     +
-	              be32_to_cpu(fore200e->stats->aal34.cells_received)    +
-	              be32_to_cpu(fore200e->stats->aal5.cells_received);
-
-    if (arg)
-	return copy_to_user(arg, &tmp, sizeof(struct sonet_stats)) ? -EFAULT : 0;	
-    
-    return 0;
-}
-
-
-static int
-fore200e_ioctl(struct atm_dev* dev, unsigned int cmd, void __user * arg)
-{
-    struct fore200e* fore200e = FORE200E_DEV(dev);
-    
-    DPRINTK(2, "ioctl cmd = 0x%x (%u), arg = 0x%p (%lu)\n", cmd, cmd, arg, (unsigned long)arg);
-
-    switch (cmd) {
-
-    case SONET_GETSTAT:
-	return fore200e_fetch_stats(fore200e, (struct sonet_stats __user *)arg);
-
-    case SONET_GETDIAG:
-	return put_user(0, (int __user *)arg) ? -EFAULT : 0;
-
-    case ATM_SETLOOP:
-	return fore200e_setloop(fore200e, (int)(unsigned long)arg);
-
-    case ATM_GETLOOP:
-	return put_user(fore200e->loop_mode, (int __user *)arg) ? -EFAULT : 0;
-
-    case ATM_QUERYLOOP:
-	return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY, (int __user *)arg) ? -EFAULT : 0;
-    }
-
-    return -ENOSYS; /* not implemented */
-}
-
-
-static int
-fore200e_change_qos(struct atm_vcc* vcc,struct atm_qos* qos, int flags)
-{
-    struct fore200e_vcc* fore200e_vcc = FORE200E_VCC(vcc);
-    struct fore200e*     fore200e     = FORE200E_DEV(vcc->dev);
-
-    if (!test_bit(ATM_VF_READY, &vcc->flags)) {
-	DPRINTK(1, "VC %d.%d.%d not ready for QoS change\n", vcc->itf, vcc->vpi, vcc->vpi);
-	return -EINVAL;
-    }
-
-    DPRINTK(2, "change_qos %d.%d.%d, "
-	    "(tx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d; "
-	    "rx: cl=%s, pcr=%d-%d, cdv=%d, max_sdu=%d), flags = 0x%x\n"
-	    "available_cell_rate = %u",
-	    vcc->itf, vcc->vpi, vcc->vci,
-	    fore200e_traffic_class[ qos->txtp.traffic_class ],
-	    qos->txtp.min_pcr, qos->txtp.max_pcr, qos->txtp.max_cdv, qos->txtp.max_sdu,
-	    fore200e_traffic_class[ qos->rxtp.traffic_class ],
-	    qos->rxtp.min_pcr, qos->rxtp.max_pcr, qos->rxtp.max_cdv, qos->rxtp.max_sdu,
-	    flags, fore200e->available_cell_rate);
-
-    if ((qos->txtp.traffic_class == ATM_CBR) && (qos->txtp.max_pcr > 0)) {
-
-	mutex_lock(&fore200e->rate_mtx);
-	if (fore200e->available_cell_rate + vcc->qos.txtp.max_pcr < qos->txtp.max_pcr) {
-	    mutex_unlock(&fore200e->rate_mtx);
-	    return -EAGAIN;
-	}
-
-	fore200e->available_cell_rate += vcc->qos.txtp.max_pcr;
-	fore200e->available_cell_rate -= qos->txtp.max_pcr;
-
-	mutex_unlock(&fore200e->rate_mtx);
-	
-	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
-	
-	/* update rate control parameters */
-	fore200e_rate_ctrl(qos, &fore200e_vcc->rate);
-
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-	return 0;
-    }
-    
-    return -EINVAL;
-}
-    
-
-static int fore200e_irq_request(struct fore200e *fore200e)
-{
-    if (request_irq(fore200e->irq, fore200e_interrupt, IRQF_SHARED, fore200e->name, fore200e->atm_dev) < 0) {
-
-	printk(FORE200E "unable to reserve IRQ %s for device %s\n",
-	       fore200e_irq_itoa(fore200e->irq), fore200e->name);
-	return -EBUSY;
-    }
-
-    printk(FORE200E "IRQ %s reserved for device %s\n",
-	   fore200e_irq_itoa(fore200e->irq), fore200e->name);
-
-#ifdef FORE200E_USE_TASKLET
-    tasklet_init(&fore200e->tx_tasklet, fore200e_tx_tasklet, (unsigned long)fore200e);
-    tasklet_init(&fore200e->rx_tasklet, fore200e_rx_tasklet, (unsigned long)fore200e);
-#endif
-
-    fore200e->state = FORE200E_STATE_IRQ;
-    return 0;
-}
-
-
-static int fore200e_get_esi(struct fore200e *fore200e)
-{
-    struct prom_data* prom = kzalloc_obj(struct prom_data);
-    int ok, i;
-
-    if (!prom)
-	return -ENOMEM;
-
-    ok = fore200e->bus->prom_read(fore200e, prom);
-    if (ok < 0) {
-	kfree(prom);
-	return -EBUSY;
-    }
-	
-    printk(FORE200E "device %s, rev. %c, S/N: %d, ESI: %pM\n",
-	   fore200e->name, 
-	   (prom->hw_revision & 0xFF) + '@',    /* probably meaningless with SBA boards */
-	   prom->serial_number & 0xFFFF, &prom->mac_addr[2]);
-	
-    for (i = 0; i < ESI_LEN; i++) {
-	fore200e->esi[ i ] = fore200e->atm_dev->esi[ i ] = prom->mac_addr[ i + 2 ];
-    }
-    
-    kfree(prom);
-
-    return 0;
-}
-
-
-static int fore200e_alloc_rx_buf(struct fore200e *fore200e)
-{
-    int scheme, magn, nbr, size, i;
-
-    struct host_bsq* bsq;
-    struct buffer*   buffer;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-	    nbr  = fore200e_rx_buf_nbr[ scheme ][ magn ];
-	    size = fore200e_rx_buf_size[ scheme ][ magn ];
-
-	    DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn);
-
-	    /* allocate the array of receive buffers */
-	    buffer = bsq->buffer = kzalloc_objs(struct buffer, nbr);
-
-	    if (buffer == NULL)
-		return -ENOMEM;
-
-	    bsq->freebuf = NULL;
-
-	    for (i = 0; i < nbr; i++) {
-
-		buffer[ i ].scheme = scheme;
-		buffer[ i ].magn   = magn;
-#ifdef FORE200E_BSQ_DEBUG
-		buffer[ i ].index  = i;
-		buffer[ i ].supplied = 0;
-#endif
-
-		/* allocate the receive buffer body */
-		if (fore200e_chunk_alloc(fore200e,
-					 &buffer[ i ].data, size, fore200e->bus->buffer_alignment,
-					 DMA_FROM_DEVICE) < 0) {
-		    
-		    while (i > 0)
-			fore200e_chunk_free(fore200e, &buffer[ --i ].data);
-		    kfree(buffer);
-		    
-		    return -ENOMEM;
-		}
-
-		/* insert the buffer into the free buffer list */
-		buffer[ i ].next = bsq->freebuf;
-		bsq->freebuf = &buffer[ i ];
-	    }
-	    /* all the buffers are free, initially */
-	    bsq->freebuf_count = nbr;
-
-#ifdef FORE200E_BSQ_DEBUG
-	    bsq_audit(3, bsq, scheme, magn);
-#endif
-	}
-    }
-
-    fore200e->state = FORE200E_STATE_ALLOC_BUF;
-    return 0;
-}
-
-
-static int fore200e_init_bs_queue(struct fore200e *fore200e)
-{
-    int scheme, magn, i;
-
-    struct host_bsq*     bsq;
-    struct cp_bsq_entry __iomem * cp_entry;
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++) {
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++) {
-
-	    DPRINTK(2, "buffer supply queue %d / %d is being initialized\n", scheme, magn);
-
-	    bsq = &fore200e->host_bsq[ scheme ][ magn ];
-
-	    /* allocate and align the array of status words */
-	    if (fore200e_dma_chunk_alloc(fore200e,
-					       &bsq->status,
-					       sizeof(enum status), 
-					       QUEUE_SIZE_BS,
-					       fore200e->bus->status_alignment) < 0) {
-		return -ENOMEM;
-	    }
-
-	    /* allocate and align the array of receive buffer descriptors */
-	    if (fore200e_dma_chunk_alloc(fore200e,
-					       &bsq->rbd_block,
-					       sizeof(struct rbd_block),
-					       QUEUE_SIZE_BS,
-					       fore200e->bus->descr_alignment) < 0) {
-		
-		fore200e_dma_chunk_free(fore200e, &bsq->status);
-		return -ENOMEM;
-	    }
-	    
-	    /* get the base address of the cp resident buffer supply queue entries */
-	    cp_entry = fore200e->virt_base + 
-		       fore200e->bus->read(&fore200e->cp_queues->cp_bsq[ scheme ][ magn ]);
-	    
-	    /* fill the host resident and cp resident buffer supply queue entries */
-	    for (i = 0; i < QUEUE_SIZE_BS; i++) {
-		
-		bsq->host_entry[ i ].status = 
-		                     FORE200E_INDEX(bsq->status.align_addr, enum status, i);
-	        bsq->host_entry[ i ].rbd_block =
-		                     FORE200E_INDEX(bsq->rbd_block.align_addr, struct rbd_block, i);
-		bsq->host_entry[ i ].rbd_block_dma =
-		                     FORE200E_DMA_INDEX(bsq->rbd_block.dma_addr, struct rbd_block, i);
-		bsq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-		
-		*bsq->host_entry[ i ].status = STATUS_FREE;
-		
-		fore200e->bus->write(FORE200E_DMA_INDEX(bsq->status.dma_addr, enum status, i), 
-				     &cp_entry[ i ].status_haddr);
-	    }
-	}
-    }
-
-    fore200e->state = FORE200E_STATE_INIT_BSQ;
-    return 0;
-}
-
-
-static int fore200e_init_rx_queue(struct fore200e *fore200e)
-{
-    struct host_rxq*     rxq =  &fore200e->host_rxq;
-    struct cp_rxq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "receive queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &rxq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_RX,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-
-    /* allocate and align the array of receive PDU descriptors */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &rxq->rpd,
-				       sizeof(struct rpd), 
-				       QUEUE_SIZE_RX,
-				       fore200e->bus->descr_alignment) < 0) {
-	
-	fore200e_dma_chunk_free(fore200e, &rxq->status);
-	return -ENOMEM;
-    }
-
-    /* get the base address of the cp resident rx queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_rxq);
-
-    /* fill the host resident and cp resident rx entries */
-    for (i=0; i < QUEUE_SIZE_RX; i++) {
-	
-	rxq->host_entry[ i ].status = 
-	                     FORE200E_INDEX(rxq->status.align_addr, enum status, i);
-	rxq->host_entry[ i ].rpd = 
-	                     FORE200E_INDEX(rxq->rpd.align_addr, struct rpd, i);
-	rxq->host_entry[ i ].rpd_dma = 
-	                     FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i);
-	rxq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*rxq->host_entry[ i ].status = STATUS_FREE;
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->status.dma_addr, enum status, i), 
-			     &cp_entry[ i ].status_haddr);
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(rxq->rpd.dma_addr, struct rpd, i),
-			     &cp_entry[ i ].rpd_haddr);
-    }
-
-    /* set the head entry of the queue */
-    rxq->head = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_RXQ;
-    return 0;
-}
-
-
-static int fore200e_init_tx_queue(struct fore200e *fore200e)
-{
-    struct host_txq*     txq =  &fore200e->host_txq;
-    struct cp_txq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "transmit queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &txq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_TX,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-
-    /* allocate and align the array of transmit PDU descriptors */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &txq->tpd,
-				       sizeof(struct tpd), 
-				       QUEUE_SIZE_TX,
-				       fore200e->bus->descr_alignment) < 0) {
-	
-	fore200e_dma_chunk_free(fore200e, &txq->status);
-	return -ENOMEM;
-    }
-
-    /* get the base address of the cp resident tx queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_txq);
-
-    /* fill the host resident and cp resident tx entries */
-    for (i=0; i < QUEUE_SIZE_TX; i++) {
-	
-	txq->host_entry[ i ].status = 
-	                     FORE200E_INDEX(txq->status.align_addr, enum status, i);
-	txq->host_entry[ i ].tpd = 
-	                     FORE200E_INDEX(txq->tpd.align_addr, struct tpd, i);
-	txq->host_entry[ i ].tpd_dma  = 
-                             FORE200E_DMA_INDEX(txq->tpd.dma_addr, struct tpd, i);
-	txq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*txq->host_entry[ i ].status = STATUS_FREE;
-	
-	fore200e->bus->write(FORE200E_DMA_INDEX(txq->status.dma_addr, enum status, i), 
-			     &cp_entry[ i ].status_haddr);
-	
-        /* although there is a one-to-one mapping of tx queue entries and tpds,
-	   we do not write here the DMA (physical) base address of each tpd into
-	   the related cp resident entry, because the cp relies on this write
-	   operation to detect that a new pdu has been submitted for tx */
-    }
-
-    /* set the head and tail entries of the queue */
-    txq->head = 0;
-    txq->tail = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_TXQ;
-    return 0;
-}
-
-
-static int fore200e_init_cmd_queue(struct fore200e *fore200e)
-{
-    struct host_cmdq*     cmdq =  &fore200e->host_cmdq;
-    struct cp_cmdq_entry __iomem * cp_entry;
-    int i;
-
-    DPRINTK(2, "command queue is being initialized\n");
-
-    /* allocate and align the array of status words */
-    if (fore200e_dma_chunk_alloc(fore200e,
-				       &cmdq->status,
-				       sizeof(enum status), 
-				       QUEUE_SIZE_CMD,
-				       fore200e->bus->status_alignment) < 0) {
-	return -ENOMEM;
-    }
-    
-    /* get the base address of the cp resident cmd queue entries */
-    cp_entry = fore200e->virt_base + fore200e->bus->read(&fore200e->cp_queues->cp_cmdq);
-
-    /* fill the host resident and cp resident cmd entries */
-    for (i=0; i < QUEUE_SIZE_CMD; i++) {
-	
-	cmdq->host_entry[ i ].status   = 
-                              FORE200E_INDEX(cmdq->status.align_addr, enum status, i);
-	cmdq->host_entry[ i ].cp_entry = &cp_entry[ i ];
-
-	*cmdq->host_entry[ i ].status = STATUS_FREE;
-
-	fore200e->bus->write(FORE200E_DMA_INDEX(cmdq->status.dma_addr, enum status, i), 
-                             &cp_entry[ i ].status_haddr);
-    }
-
-    /* set the head entry of the queue */
-    cmdq->head = 0;
-
-    fore200e->state = FORE200E_STATE_INIT_CMDQ;
-    return 0;
-}
-
-
-static void fore200e_param_bs_queue(struct fore200e *fore200e,
-				    enum buffer_scheme scheme,
-				    enum buffer_magn magn, int queue_length,
-				    int pool_size, int supply_blksize)
-{
-    struct bs_spec __iomem * bs_spec = &fore200e->cp_queues->init.bs_spec[ scheme ][ magn ];
-
-    fore200e->bus->write(queue_length,                           &bs_spec->queue_length);
-    fore200e->bus->write(fore200e_rx_buf_size[ scheme ][ magn ], &bs_spec->buffer_size);
-    fore200e->bus->write(pool_size,                              &bs_spec->pool_size);
-    fore200e->bus->write(supply_blksize,                         &bs_spec->supply_blksize);
-}
-
-
-static int fore200e_initialize(struct fore200e *fore200e)
-{
-    struct cp_queues __iomem * cpq;
-    int               ok, scheme, magn;
-
-    DPRINTK(2, "device %s being initialized\n", fore200e->name);
-
-    mutex_init(&fore200e->rate_mtx);
-    spin_lock_init(&fore200e->q_lock);
-
-    cpq = fore200e->cp_queues = fore200e->virt_base + FORE200E_CP_QUEUES_OFFSET;
-
-    /* enable cp to host interrupts */
-    fore200e->bus->write(1, &cpq->imask);
-
-    if (fore200e->bus->irq_enable)
-	fore200e->bus->irq_enable(fore200e);
-    
-    fore200e->bus->write(NBR_CONNECT, &cpq->init.num_connect);
-
-    fore200e->bus->write(QUEUE_SIZE_CMD, &cpq->init.cmd_queue_len);
-    fore200e->bus->write(QUEUE_SIZE_RX,  &cpq->init.rx_queue_len);
-    fore200e->bus->write(QUEUE_SIZE_TX,  &cpq->init.tx_queue_len);
-
-    fore200e->bus->write(RSD_EXTENSION,  &cpq->init.rsd_extension);
-    fore200e->bus->write(TSD_EXTENSION,  &cpq->init.tsd_extension);
-
-    for (scheme = 0; scheme < BUFFER_SCHEME_NBR; scheme++)
-	for (magn = 0; magn < BUFFER_MAGN_NBR; magn++)
-	    fore200e_param_bs_queue(fore200e, scheme, magn,
-				    QUEUE_SIZE_BS, 
-				    fore200e_rx_buf_nbr[ scheme ][ magn ],
-				    RBD_BLK_SIZE);
-
-    /* issue the initialize command */
-    fore200e->bus->write(STATUS_PENDING,    &cpq->init.status);
-    fore200e->bus->write(OPCODE_INITIALIZE, &cpq->init.opcode);
-
-    ok = fore200e_io_poll(fore200e, &cpq->init.status, STATUS_COMPLETE, 3000);
-    if (ok == 0) {
-	printk(FORE200E "device %s initialization failed\n", fore200e->name);
-	return -ENODEV;
-    }
-
-    printk(FORE200E "device %s initialized\n", fore200e->name);
-
-    fore200e->state = FORE200E_STATE_INITIALIZE;
-    return 0;
-}
-
-
-static void fore200e_monitor_putc(struct fore200e *fore200e, char c)
-{
-    struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
-
-#if 0
-    printk("%c", c);
-#endif
-    fore200e->bus->write(((u32) c) | FORE200E_CP_MONITOR_UART_AVAIL, &monitor->soft_uart.send);
-}
-
-
-static int fore200e_monitor_getc(struct fore200e *fore200e)
-{
-    struct cp_monitor __iomem * monitor = fore200e->cp_monitor;
-    unsigned long      timeout = jiffies + msecs_to_jiffies(50);
-    int                c;
-
-    while (time_before(jiffies, timeout)) {
-
-	c = (int) fore200e->bus->read(&monitor->soft_uart.recv);
-
-	if (c & FORE200E_CP_MONITOR_UART_AVAIL) {
-
-	    fore200e->bus->write(FORE200E_CP_MONITOR_UART_FREE, &monitor->soft_uart.recv);
-#if 0
-	    printk("%c", c & 0xFF);
-#endif
-	    return c & 0xFF;
-	}
-    }
-
-    return -1;
-}
-
-
-static void fore200e_monitor_puts(struct fore200e *fore200e, char *str)
-{
-    while (*str) {
-
-	/* the i960 monitor doesn't accept any new character if it has something to say */
-	while (fore200e_monitor_getc(fore200e) >= 0);
-	
-	fore200e_monitor_putc(fore200e, *str++);
-    }
-
-    while (fore200e_monitor_getc(fore200e) >= 0);
-}
-
-#ifdef __LITTLE_ENDIAN
-#define FW_EXT ".bin"
-#else
-#define FW_EXT "_ecd.bin2"
-#endif
-
-static int fore200e_load_and_start_fw(struct fore200e *fore200e)
-{
-    const struct firmware *firmware;
-    const struct fw_header *fw_header;
-    const __le32 *fw_data;
-    u32 fw_size;
-    u32 __iomem *load_addr;
-    char buf[48];
-    int err;
-
-    sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
-    if ((err = request_firmware(&firmware, buf, fore200e->dev)) < 0) {
-	printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
-	return err;
-    }
-
-    fw_data = (const __le32 *)firmware->data;
-    fw_size = firmware->size / sizeof(u32);
-    fw_header = (const struct fw_header *)firmware->data;
-    load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset);
-
-    DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n",
-	    fore200e->name, load_addr, fw_size);
-
-    if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) {
-	printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name);
-	goto release;
-    }
-
-    for (; fw_size--; fw_data++, load_addr++)
-	fore200e->bus->write(le32_to_cpu(*fw_data), load_addr);
-
-    DPRINTK(2, "device %s firmware being started\n", fore200e->name);
-
-#if defined(__sparc_v9__)
-    /* reported to be required by SBA cards on some sparc64 hosts */
-    fore200e_spin(100);
-#endif
-
-    sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset));
-    fore200e_monitor_puts(fore200e, buf);
-
-    if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) {
-	printk(FORE200E "device %s firmware didn't start\n", fore200e->name);
-	goto release;
-    }
-
-    printk(FORE200E "device %s firmware started\n", fore200e->name);
-
-    fore200e->state = FORE200E_STATE_START_FW;
-    err = 0;
-
-release:
-    release_firmware(firmware);
-    return err;
-}
-
-
-static int fore200e_register(struct fore200e *fore200e, struct device *parent)
-{
-    struct atm_dev* atm_dev;
-
-    DPRINTK(2, "device %s being registered\n", fore200e->name);
-
-    atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops,
-                               -1, NULL);
-    if (atm_dev == NULL) {
-	printk(FORE200E "unable to register device %s\n", fore200e->name);
-	return -ENODEV;
-    }
-
-    atm_dev->dev_data = fore200e;
-    fore200e->atm_dev = atm_dev;
-
-    atm_dev->ci_range.vpi_bits = FORE200E_VPI_BITS;
-    atm_dev->ci_range.vci_bits = FORE200E_VCI_BITS;
-
-    fore200e->available_cell_rate = ATM_OC3_PCR;
-
-    fore200e->state = FORE200E_STATE_REGISTER;
-    return 0;
-}
-
-
-static int fore200e_init(struct fore200e *fore200e, struct device *parent)
-{
-    if (fore200e_register(fore200e, parent) < 0)
-	return -ENODEV;
-    
-    if (fore200e->bus->configure(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e->bus->map(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_reset(fore200e, 1) < 0)
-	return -ENODEV;
-
-    if (fore200e_load_and_start_fw(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_initialize(fore200e) < 0)
-	return -ENODEV;
-
-    if (fore200e_init_cmd_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_tx_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_rx_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_init_bs_queue(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_alloc_rx_buf(fore200e) < 0)
-	return -ENOMEM;
-
-    if (fore200e_get_esi(fore200e) < 0)
-	return -EIO;
-
-    if (fore200e_irq_request(fore200e) < 0)
-	return -EBUSY;
-
-    fore200e_supply(fore200e);
-
-    /* all done, board initialization is now complete */
-    fore200e->state = FORE200E_STATE_COMPLETE;
-    return 0;
-}
-
-#ifdef CONFIG_SBUS
-static int fore200e_sba_probe(struct platform_device *op)
-{
-	struct fore200e *fore200e;
-	static int index = 0;
-	int err;
-
-	fore200e = kzalloc_obj(struct fore200e);
-	if (!fore200e)
-		return -ENOMEM;
-
-	fore200e->bus = &fore200e_sbus_ops;
-	fore200e->dev = &op->dev;
-	fore200e->irq = op->archdata.irqs[0];
-	fore200e->phys_base = op->resource[0].start;
-
-	sprintf(fore200e->name, "SBA-200E-%d", index);
-
-	err = fore200e_init(fore200e, &op->dev);
-	if (err < 0) {
-		fore200e_shutdown(fore200e);
-		kfree(fore200e);
-		return err;
-	}
-
-	index++;
-	dev_set_drvdata(&op->dev, fore200e);
-
-	return 0;
-}
-
-static void fore200e_sba_remove(struct platform_device *op)
-{
-	struct fore200e *fore200e = dev_get_drvdata(&op->dev);
-
-	fore200e_shutdown(fore200e);
-	kfree(fore200e);
-}
-
-static const struct of_device_id fore200e_sba_match[] = {
-	{
-		.name = SBA200E_PROM_NAME,
-	},
-	{},
-};
-MODULE_DEVICE_TABLE(of, fore200e_sba_match);
-
-static struct platform_driver fore200e_sba_driver = {
-	.driver = {
-		.name = "fore_200e",
-		.of_match_table = fore200e_sba_match,
-	},
-	.probe		= fore200e_sba_probe,
-	.remove		= fore200e_sba_remove,
-};
-#endif
-
-#ifdef CONFIG_PCI
-static int fore200e_pca_detect(struct pci_dev *pci_dev,
-			       const struct pci_device_id *pci_ent)
-{
-    struct fore200e* fore200e;
-    int err = 0;
-    static int index = 0;
-
-    if (pci_enable_device(pci_dev)) {
-	err = -EINVAL;
-	goto out;
-    }
-
-    if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32))) {
-	err = -EINVAL;
-	goto out;
-    }
-    
-    fore200e = kzalloc_obj(struct fore200e);
-    if (fore200e == NULL) {
-	err = -ENOMEM;
-	goto out_disable;
-    }
-
-    fore200e->bus       = &fore200e_pci_ops;
-    fore200e->dev	= &pci_dev->dev;
-    fore200e->irq       = pci_dev->irq;
-    fore200e->phys_base = pci_resource_start(pci_dev, 0);
-
-    sprintf(fore200e->name, "PCA-200E-%d", index - 1);
-
-    pci_set_master(pci_dev);
-
-    printk(FORE200E "device PCA-200E found at 0x%lx, IRQ %s\n",
-	   fore200e->phys_base, fore200e_irq_itoa(fore200e->irq));
-
-    sprintf(fore200e->name, "PCA-200E-%d", index);
-
-    err = fore200e_init(fore200e, &pci_dev->dev);
-    if (err < 0) {
-	fore200e_shutdown(fore200e);
-	goto out_free;
-    }
-
-    ++index;
-    pci_set_drvdata(pci_dev, fore200e);
-
-out:
-    return err;
-
-out_free:
-    kfree(fore200e);
-out_disable:
-    pci_disable_device(pci_dev);
-    goto out;
-}
-
-
-static void fore200e_pca_remove_one(struct pci_dev *pci_dev)
-{
-    struct fore200e *fore200e;
-
-    fore200e = pci_get_drvdata(pci_dev);
-
-    fore200e_shutdown(fore200e);
-    kfree(fore200e);
-    pci_disable_device(pci_dev);
-}
-
-
-static const struct pci_device_id fore200e_pca_tbl[] = {
-    { PCI_VENDOR_ID_FORE, PCI_DEVICE_ID_FORE_PCA200E, PCI_ANY_ID, PCI_ANY_ID },
-    { 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, fore200e_pca_tbl);
-
-static struct pci_driver fore200e_pca_driver = {
-    .name =     "fore_200e",
-    .probe =    fore200e_pca_detect,
-    .remove =   fore200e_pca_remove_one,
-    .id_table = fore200e_pca_tbl,
-};
-#endif
-
-static int __init fore200e_module_init(void)
-{
-	int err = 0;
-
-	printk(FORE200E "FORE Systems 200E-series ATM driver - version " FORE200E_VERSION "\n");
-
-#ifdef CONFIG_SBUS
-	err = platform_driver_register(&fore200e_sba_driver);
-	if (err)
-		return err;
-#endif
-
-#ifdef CONFIG_PCI
-	err = pci_register_driver(&fore200e_pca_driver);
-#endif
-
-#ifdef CONFIG_SBUS
-	if (err)
-		platform_driver_unregister(&fore200e_sba_driver);
-#endif
-
-	return err;
-}
-
-static void __exit fore200e_module_cleanup(void)
-{
-#ifdef CONFIG_PCI
-	pci_unregister_driver(&fore200e_pca_driver);
-#endif
-#ifdef CONFIG_SBUS
-	platform_driver_unregister(&fore200e_sba_driver);
-#endif
-}
-
-static int
-fore200e_proc_read(struct atm_dev *dev, loff_t* pos, char* page)
-{
-    struct fore200e*     fore200e  = FORE200E_DEV(dev);
-    struct fore200e_vcc* fore200e_vcc;
-    struct atm_vcc*      vcc;
-    int                  i, len, left = *pos;
-    unsigned long        flags;
-
-    if (!left--) {
-
-	if (fore200e_getstats(fore200e) < 0)
-	    return -EIO;
-
-	len = sprintf(page,"\n"
-		       " device:\n"
-		       "   internal name:\t\t%s\n", fore200e->name);
-
-	/* print bus-specific information */
-	if (fore200e->bus->proc_read)
-	    len += fore200e->bus->proc_read(fore200e, page + len);
-	
-	len += sprintf(page + len,
-		"   interrupt line:\t\t%s\n"
-		"   physical base address:\t0x%p\n"
-		"   virtual base address:\t0x%p\n"
-		"   factory address (ESI):\t%pM\n"
-		"   board serial number:\t\t%d\n\n",
-		fore200e_irq_itoa(fore200e->irq),
-		(void*)fore200e->phys_base,
-		fore200e->virt_base,
-		fore200e->esi,
-		fore200e->esi[4] * 256 + fore200e->esi[5]);
-
-	return len;
-    }
-
-    if (!left--)
-	return sprintf(page,
-		       "   free small bufs, scheme 1:\t%d\n"
-		       "   free large bufs, scheme 1:\t%d\n"
-		       "   free small bufs, scheme 2:\t%d\n"
-		       "   free large bufs, scheme 2:\t%d\n",
-		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_SMALL ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_ONE ][ BUFFER_MAGN_LARGE ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_SMALL ].freebuf_count,
-		       fore200e->host_bsq[ BUFFER_SCHEME_TWO ][ BUFFER_MAGN_LARGE ].freebuf_count);
-
-    if (!left--) {
-	u32 hb = fore200e->bus->read(&fore200e->cp_queues->heartbeat);
-
-	len = sprintf(page,"\n\n"
-		      " cell processor:\n"
-		      "   heartbeat state:\t\t");
-	
-	if (hb >> 16 != 0xDEAD)
-	    len += sprintf(page + len, "0x%08x\n", hb);
-	else
-	    len += sprintf(page + len, "*** FATAL ERROR %04x ***\n", hb & 0xFFFF);
-
-	return len;
-    }
-
-    if (!left--) {
-	static const char* media_name[] = {
-	    "unshielded twisted pair",
-	    "multimode optical fiber ST",
-	    "multimode optical fiber SC",
-	    "single-mode optical fiber ST",
-	    "single-mode optical fiber SC",
-	    "unknown"
-	};
-
-	static const char* oc3_mode[] = {
-	    "normal operation",
-	    "diagnostic loopback",
-	    "line loopback",
-	    "unknown"
-	};
-
-	u32 fw_release     = fore200e->bus->read(&fore200e->cp_queues->fw_release);
-	u32 mon960_release = fore200e->bus->read(&fore200e->cp_queues->mon960_release);
-	u32 oc3_revision   = fore200e->bus->read(&fore200e->cp_queues->oc3_revision);
-	u32 media_index    = FORE200E_MEDIA_INDEX(fore200e->bus->read(&fore200e->cp_queues->media_type));
-	u32 oc3_index;
-
-	if (media_index > 4)
-		media_index = 5;
-	
-	switch (fore200e->loop_mode) {
-	    case ATM_LM_NONE:    oc3_index = 0;
-		                 break;
-	    case ATM_LM_LOC_PHY: oc3_index = 1;
-		                 break;
-	    case ATM_LM_RMT_PHY: oc3_index = 2;
-		                 break;
-	    default:             oc3_index = 3;
-	}
-
-	return sprintf(page,
-		       "   firmware release:\t\t%d.%d.%d\n"
-		       "   monitor release:\t\t%d.%d\n"
-		       "   media type:\t\t\t%s\n"
-		       "   OC-3 revision:\t\t0x%x\n"
-                       "   OC-3 mode:\t\t\t%s",
-		       fw_release >> 16, fw_release << 16 >> 24,  fw_release << 24 >> 24,
-		       mon960_release >> 16, mon960_release << 16 >> 16,
-		       media_name[ media_index ],
-		       oc3_revision,
-		       oc3_mode[ oc3_index ]);
-    }
-
-    if (!left--) {
-	struct cp_monitor __iomem * cp_monitor = fore200e->cp_monitor;
-
-	return sprintf(page,
-		       "\n\n"
-		       " monitor:\n"
-		       "   version number:\t\t%d\n"
-		       "   boot status word:\t\t0x%08x\n",
-		       fore200e->bus->read(&cp_monitor->mon_version),
-		       fore200e->bus->read(&cp_monitor->bstat));
-    }
-
-    if (!left--)
-	return sprintf(page,
-		       "\n"
-		       " device statistics:\n"
-		       "  4b5b:\n"
-		       "     crc_header_errors:\t\t%10u\n"
-		       "     framing_errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->phy.crc_header_errors),
-		       be32_to_cpu(fore200e->stats->phy.framing_errors));
-    
-    if (!left--)
-	return sprintf(page, "\n"
-		       "  OC-3:\n"
-		       "     section_bip8_errors:\t%10u\n"
-		       "     path_bip8_errors:\t\t%10u\n"
-		       "     line_bip24_errors:\t\t%10u\n"
-		       "     line_febe_errors:\t\t%10u\n"
-		       "     path_febe_errors:\t\t%10u\n"
-		       "     corr_hcs_errors:\t\t%10u\n"
-		       "     ucorr_hcs_errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->oc3.section_bip8_errors),
-		       be32_to_cpu(fore200e->stats->oc3.path_bip8_errors),
-		       be32_to_cpu(fore200e->stats->oc3.line_bip24_errors),
-		       be32_to_cpu(fore200e->stats->oc3.line_febe_errors),
-		       be32_to_cpu(fore200e->stats->oc3.path_febe_errors),
-		       be32_to_cpu(fore200e->stats->oc3.corr_hcs_errors),
-		       be32_to_cpu(fore200e->stats->oc3.ucorr_hcs_errors));
-
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   ATM:\t\t\t\t     cells\n"
-		       "     TX:\t\t\t%10u\n"
-		       "     RX:\t\t\t%10u\n"
-		       "     vpi out of range:\t\t%10u\n"
-		       "     vpi no conn:\t\t%10u\n"
-		       "     vci out of range:\t\t%10u\n"
-		       "     vci no conn:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->atm.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->atm.cells_received),
-		       be32_to_cpu(fore200e->stats->atm.vpi_bad_range),
-		       be32_to_cpu(fore200e->stats->atm.vpi_no_conn),
-		       be32_to_cpu(fore200e->stats->atm.vci_bad_range),
-		       be32_to_cpu(fore200e->stats->atm.vci_no_conn));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL0:\t\t\t     cells\n"
-		       "     TX:\t\t\t%10u\n"
-		       "     RX:\t\t\t%10u\n"
-		       "     dropped:\t\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal0.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal0.cells_received),
-		       be32_to_cpu(fore200e->stats->aal0.cells_dropped));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL3/4:\n"
-		       "     SAR sublayer:\t\t     cells\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       CRC errors:\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n\n"
-		       "     CS  sublayer:\t\t      PDUs\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal34.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal34.cells_received),
-		       be32_to_cpu(fore200e->stats->aal34.cells_dropped),
-		       be32_to_cpu(fore200e->stats->aal34.cells_crc_errors),
-		       be32_to_cpu(fore200e->stats->aal34.cells_protocol_errors),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_transmitted),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_received),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_dropped),
-		       be32_to_cpu(fore200e->stats->aal34.cspdus_protocol_errors));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AAL5:\n"
-		       "     SAR sublayer:\t\t     cells\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       congestions:\t\t%10u\n\n"
-		       "     CS  sublayer:\t\t      PDUs\n"
-		       "       TX:\t\t\t%10u\n"
-		       "       RX:\t\t\t%10u\n"
-		       "       dropped:\t\t\t%10u\n"
-		       "       CRC errors:\t\t%10u\n"
-		       "       protocol errors:\t\t%10u\n",
-		       be32_to_cpu(fore200e->stats->aal5.cells_transmitted),
-		       be32_to_cpu(fore200e->stats->aal5.cells_received),
-		       be32_to_cpu(fore200e->stats->aal5.cells_dropped),
-		       be32_to_cpu(fore200e->stats->aal5.congestion_experienced),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_transmitted),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_received),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_dropped),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_crc_errors),
-		       be32_to_cpu(fore200e->stats->aal5.cspdus_protocol_errors));
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       "   AUX:\t\t       allocation failures\n"
-		       "     small b1:\t\t\t%10u\n"
-		       "     large b1:\t\t\t%10u\n"
-		       "     small b2:\t\t\t%10u\n"
-		       "     large b2:\t\t\t%10u\n"
-		       "     RX PDUs:\t\t\t%10u\n"
-		       "     TX PDUs:\t\t\t%10lu\n",
-		       be32_to_cpu(fore200e->stats->aux.small_b1_failed),
-		       be32_to_cpu(fore200e->stats->aux.large_b1_failed),
-		       be32_to_cpu(fore200e->stats->aux.small_b2_failed),
-		       be32_to_cpu(fore200e->stats->aux.large_b2_failed),
-		       be32_to_cpu(fore200e->stats->aux.rpd_alloc_failed),
-		       fore200e->tx_sat);
-    
-    if (!left--)
-	return sprintf(page,"\n"
-		       " receive carrier:\t\t\t%s\n",
-		       fore200e->stats->aux.receive_carrier ? "ON" : "OFF!");
-    
-    if (!left--) {
-        return sprintf(page,"\n"
-		       " VCCs:\n  address   VPI VCI   AAL "
-		       "TX PDUs   TX min/max size  RX PDUs   RX min/max size\n");
-    }
-
-    for (i = 0; i < NBR_CONNECT; i++) {
-
-	vcc = fore200e->vc_map[i].vcc;
-
-	if (vcc == NULL)
-	    continue;
-
-	spin_lock_irqsave(&fore200e->q_lock, flags);
-
-	if (vcc && test_bit(ATM_VF_READY, &vcc->flags) && !left--) {
-
-	    fore200e_vcc = FORE200E_VCC(vcc);
-	    ASSERT(fore200e_vcc);
-
-	    len = sprintf(page,
-			  "  %pK  %03d %05d %1d   %09lu %05d/%05d      %09lu %05d/%05d\n",
-			  vcc,
-			  vcc->vpi, vcc->vci, fore200e_atm2fore_aal(vcc->qos.aal),
-			  fore200e_vcc->tx_pdu,
-			  fore200e_vcc->tx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->tx_min_pdu,
-			  fore200e_vcc->tx_max_pdu,
-			  fore200e_vcc->rx_pdu,
-			  fore200e_vcc->rx_min_pdu > 0xFFFF ? 0 : fore200e_vcc->rx_min_pdu,
-			  fore200e_vcc->rx_max_pdu);
-
-	    spin_unlock_irqrestore(&fore200e->q_lock, flags);
-	    return len;
-	}
-
-	spin_unlock_irqrestore(&fore200e->q_lock, flags);
-    }
-    
-    return 0;
-}
-
-module_init(fore200e_module_init);
-module_exit(fore200e_module_cleanup);
-
-
-static const struct atmdev_ops fore200e_ops = {
-	.open       = fore200e_open,
-	.close      = fore200e_close,
-	.ioctl      = fore200e_ioctl,
-	.send       = fore200e_send,
-	.change_qos = fore200e_change_qos,
-	.proc_read  = fore200e_proc_read,
-	.owner      = THIS_MODULE
-};
-
-MODULE_LICENSE("GPL");
-#ifdef CONFIG_PCI
-#ifdef __LITTLE_ENDIAN__
-MODULE_FIRMWARE("pca200e.bin");
-#else
-MODULE_FIRMWARE("pca200e_ecd.bin2");
-#endif
-#endif /* CONFIG_PCI */
-#ifdef CONFIG_SBUS
-MODULE_FIRMWARE("sba200e_ecd.bin2");
-#endif
diff --git a/drivers/atm/fore200e.h b/drivers/atm/fore200e.h
deleted file mode 100644
index 5d95fe9..0000000
--- a/drivers/atm/fore200e.h
+++ /dev/null
@@ -1,973 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _FORE200E_H
-#define _FORE200E_H
-
-#ifdef __KERNEL__
-
-/* rx buffer sizes */
-
-#define SMALL_BUFFER_SIZE    384     /* size of small buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
-#define LARGE_BUFFER_SIZE    4032    /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
-
-
-#define RBD_BLK_SIZE	     32      /* nbr of supplied rx buffers per rbd */
-
-
-#define MAX_PDU_SIZE	     65535   /* maximum PDU size supported by AALs */
-
-
-#define BUFFER_S1_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 1 */
-#define BUFFER_L1_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 1 */
-
-#define BUFFER_S2_SIZE       SMALL_BUFFER_SIZE    /* size of small buffers, scheme 2 */
-#define BUFFER_L2_SIZE       LARGE_BUFFER_SIZE    /* size of large buffers, scheme 2 */
-
-#define BUFFER_S1_NBR        (RBD_BLK_SIZE * 6)
-#define BUFFER_L1_NBR        (RBD_BLK_SIZE * 4)
-
-#define BUFFER_S2_NBR        (RBD_BLK_SIZE * 6)
-#define BUFFER_L2_NBR        (RBD_BLK_SIZE * 4)
-
-
-#define QUEUE_SIZE_CMD       16	     /* command queue capacity       */
-#define QUEUE_SIZE_RX	     64	     /* receive queue capacity       */
-#define QUEUE_SIZE_TX	     256     /* transmit queue capacity      */
-#define QUEUE_SIZE_BS        32	     /* buffer supply queue capacity */
-
-#define FORE200E_VPI_BITS     0
-#define FORE200E_VCI_BITS    10
-#define NBR_CONNECT          (1 << (FORE200E_VPI_BITS + FORE200E_VCI_BITS)) /* number of connections */
-
-
-#define TSD_FIXED            2
-#define TSD_EXTENSION        0
-#define TSD_NBR              (TSD_FIXED + TSD_EXTENSION)
-
-
-/* the cp starts putting a received PDU into one *small* buffer,
-   then it uses a number of *large* buffers for the trailing data. 
-   we compute here the total number of receive segment descriptors 
-   required to hold the largest possible PDU */
-
-#define RSD_REQUIRED  (((MAX_PDU_SIZE - SMALL_BUFFER_SIZE + LARGE_BUFFER_SIZE) / LARGE_BUFFER_SIZE) + 1)
-
-#define RSD_FIXED     3
-
-/* RSD_REQUIRED receive segment descriptors are enough to describe a max-sized PDU,
-   but we have to keep the size of the receive PDU descriptor multiple of 32 bytes,
-   so we add one extra RSD to RSD_EXTENSION 
-   (WARNING: THIS MAY CHANGE IF BUFFER SIZES ARE MODIFIED) */
-
-#define RSD_EXTENSION  ((RSD_REQUIRED - RSD_FIXED) + 1)
-#define RSD_NBR         (RSD_FIXED + RSD_EXTENSION)
-
-
-#define FORE200E_DEV(d)          ((struct fore200e*)((d)->dev_data))
-#define FORE200E_VCC(d)          ((struct fore200e_vcc*)((d)->dev_data))
-
-/* bitfields endian games */
-
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-#define BITFIELD2(b1, b2)                    b1; b2;
-#define BITFIELD3(b1, b2, b3)                b1; b2; b3;
-#define BITFIELD4(b1, b2, b3, b4)            b1; b2; b3; b4;
-#define BITFIELD5(b1, b2, b3, b4, b5)        b1; b2; b3; b4; b5;
-#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b1; b2; b3; b4; b5; b6;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-#define BITFIELD2(b1, b2)                                    b2; b1;
-#define BITFIELD3(b1, b2, b3)                            b3; b2; b1;
-#define BITFIELD4(b1, b2, b3, b4)                    b4; b3; b2; b1;
-#define BITFIELD5(b1, b2, b3, b4, b5)            b5; b4; b3; b2; b1;
-#define BITFIELD6(b1, b2, b3, b4, b5, b6)    b6; b5; b4; b3; b2; b1;
-#else
-#error unknown bitfield endianess
-#endif
-
- 
-/* ATM cell header (minus HEC byte) */
-
-typedef struct atm_header {
-    BITFIELD5( 
-        u32 clp :  1,    /* cell loss priority         */
-        u32 plt :  3,    /* payload type               */
-        u32 vci : 16,    /* virtual channel identifier */
-        u32 vpi :  8,    /* virtual path identifier    */
-        u32 gfc :  4     /* generic flow control       */
-   )
-} atm_header_t;
-
-
-/* ATM adaptation layer id */
-
-typedef enum fore200e_aal {
-    FORE200E_AAL0  = 0,
-    FORE200E_AAL34 = 4,
-    FORE200E_AAL5  = 5,
-} fore200e_aal_t;
-
-
-/* transmit PDU descriptor specification */
-
-typedef struct tpd_spec {
-    BITFIELD4(
-        u32               length : 16,    /* total PDU length            */
-        u32               nseg   :  8,    /* number of transmit segments */
-        enum fore200e_aal aal    :  4,    /* adaptation layer            */
-        u32               intr   :  4     /* interrupt requested         */
-    )
-} tpd_spec_t;
-
-
-/* transmit PDU rate control */
-
-typedef struct tpd_rate
-{
-    BITFIELD2( 
-        u32 idle_cells : 16,    /* number of idle cells to insert   */
-        u32 data_cells : 16     /* number of data cells to transmit */
-    )
-} tpd_rate_t;
-
-
-/* transmit segment descriptor */
-
-typedef struct tsd {
-    u32 buffer;    /* transmit buffer DMA address */
-    u32 length;    /* number of bytes in buffer   */
-} tsd_t;
-
-
-/* transmit PDU descriptor */
-
-typedef struct tpd {
-    struct atm_header atm_header;        /* ATM header minus HEC byte    */
-    struct tpd_spec   spec;              /* tpd specification            */
-    struct tpd_rate   rate;              /* tpd rate control             */
-    u32               pad;               /* reserved                     */
-    struct tsd        tsd[ TSD_NBR ];    /* transmit segment descriptors */
-} tpd_t;
-
-
-/* receive segment descriptor */
-
-typedef struct rsd {
-    u32 handle;    /* host supplied receive buffer handle */
-    u32 length;    /* number of bytes in buffer           */
-} rsd_t;
-
-
-/* receive PDU descriptor */
-
-typedef struct rpd {
-    struct atm_header atm_header;        /* ATM header minus HEC byte   */
-    u32               nseg;              /* number of receive segments  */
-    struct rsd        rsd[ RSD_NBR ];    /* receive segment descriptors */
-} rpd_t;
-
-
-/* buffer scheme */
-
-typedef enum buffer_scheme {
-    BUFFER_SCHEME_ONE,
-    BUFFER_SCHEME_TWO,
-    BUFFER_SCHEME_NBR    /* always last */
-} buffer_scheme_t;
-
-
-/* buffer magnitude */
-
-typedef enum buffer_magn {
-    BUFFER_MAGN_SMALL,
-    BUFFER_MAGN_LARGE,
-    BUFFER_MAGN_NBR    /* always last */
-} buffer_magn_t;
-
-
-/* receive buffer descriptor */
-
-typedef struct rbd {
-    u32 handle;          /* host supplied handle            */
-    u32 buffer_haddr;    /* host DMA address of host buffer */
-} rbd_t;
-
-
-/* receive buffer descriptor block */
-
-typedef struct rbd_block {
-    struct rbd rbd[ RBD_BLK_SIZE ];    /* receive buffer descriptor */
-} rbd_block_t;
-
-
-/* tpd DMA address */
-
-typedef struct tpd_haddr {
-    BITFIELD3( 
-        u32 size  :  4,    /* tpd size expressed in 32 byte blocks     */
-        u32 pad   :  1,    /* reserved                                 */
-        u32 haddr : 27     /* tpd DMA addr aligned on 32 byte boundary */
-    )
-} tpd_haddr_t;
-
-#define TPD_HADDR_SHIFT 5  /* addr aligned on 32 byte boundary */
-
-/* cp resident transmit queue entry */
-
-typedef struct cp_txq_entry {
-    struct tpd_haddr tpd_haddr;       /* host DMA address of tpd                */
-    u32              status_haddr;    /* host DMA address of completion status  */
-} cp_txq_entry_t;
-
-
-/* cp resident receive queue entry */
-
-typedef struct cp_rxq_entry {
-    u32 rpd_haddr;       /* host DMA address of rpd                */
-    u32 status_haddr;    /* host DMA address of completion status  */
-} cp_rxq_entry_t;
-
-
-/* cp resident buffer supply queue entry */
-
-typedef struct cp_bsq_entry {
-    u32 rbd_block_haddr;    /* host DMA address of rbd block          */
-    u32 status_haddr;       /* host DMA address of completion status  */
-} cp_bsq_entry_t;
-
-
-/* completion status */
-
-typedef volatile enum status {
-    STATUS_PENDING  = (1<<0),    /* initial status (written by host)  */
-    STATUS_COMPLETE = (1<<1),    /* completion status (written by cp) */
-    STATUS_FREE     = (1<<2),    /* initial status (written by host)  */
-    STATUS_ERROR    = (1<<3)     /* completion status (written by cp) */
-} status_t;
-
-
-/* cp operation code */
-
-typedef enum opcode {
-    OPCODE_INITIALIZE = 1,          /* initialize board                       */
-    OPCODE_ACTIVATE_VCIN,           /* activate incoming VCI                  */
-    OPCODE_ACTIVATE_VCOUT,          /* activate outgoing VCI                  */
-    OPCODE_DEACTIVATE_VCIN,         /* deactivate incoming VCI                */
-    OPCODE_DEACTIVATE_VCOUT,        /* deactivate incoing VCI                 */
-    OPCODE_GET_STATS,               /* get board statistics                   */
-    OPCODE_SET_OC3,                 /* set OC-3 registers                     */
-    OPCODE_GET_OC3,                 /* get OC-3 registers                     */
-    OPCODE_RESET_STATS,             /* reset board statistics                 */
-    OPCODE_GET_PROM,                /* get expansion PROM data (PCI specific) */
-    OPCODE_SET_VPI_BITS,            /* set x bits of those decoded by the
-				       firmware to be low order bits from
-				       the VPI field of the ATM cell header   */
-    OPCODE_REQUEST_INTR = (1<<7)    /* request interrupt                      */
-} opcode_t;
-
-
-/* virtual path / virtual channel identifiers */
-
-typedef struct vpvc {
-    BITFIELD3(
-        u32 vci : 16,    /* virtual channel identifier */
-        u32 vpi :  8,    /* virtual path identifier    */
-        u32 pad :  8     /* reserved                   */
-    )
-} vpvc_t;
-
-
-/* activate VC command opcode */
-
-typedef struct activate_opcode {
-    BITFIELD4( 
-        enum opcode        opcode : 8,    /* cp opcode        */
-        enum fore200e_aal  aal    : 8,    /* adaptation layer */
-        enum buffer_scheme scheme : 8,    /* buffer scheme    */
-        u32  pad                  : 8     /* reserved         */
-   )
-} activate_opcode_t;
-
-
-/* activate VC command block */
-
-typedef struct activate_block {
-    struct activate_opcode  opcode;    /* activate VC command opcode */
-    struct vpvc             vpvc;      /* VPI/VCI                    */
-    u32                     mtu;       /* for AAL0 only              */
-
-} activate_block_t;
-
-
-/* deactivate VC command opcode */
-
-typedef struct deactivate_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} deactivate_opcode_t;
-
-
-/* deactivate VC command block */
-
-typedef struct deactivate_block {
-    struct deactivate_opcode opcode;    /* deactivate VC command opcode */
-    struct vpvc              vpvc;      /* VPI/VCI                      */
-} deactivate_block_t;
-
-
-/* OC-3 registers */
-
-typedef struct oc3_regs {
-    u32 reg[ 128 ];    /* see the PMC Sierra PC5346 S/UNI-155-Lite
-			  Saturn User Network Interface documentation
-			  for a description of the OC-3 chip registers */
-} oc3_regs_t;
-
-
-/* set/get OC-3 regs command opcode */
-
-typedef struct oc3_opcode {
-    BITFIELD4(
-        enum opcode opcode : 8,    /* cp opcode                           */
-	u32         reg    : 8,    /* register index                      */
-	u32         value  : 8,    /* register value                      */
-	u32         mask   : 8     /* register mask that specifies which
-				      bits of the register value field
-				      are significant                     */
-    )
-} oc3_opcode_t;
-
-
-/* set/get OC-3 regs command block */
-
-typedef struct oc3_block {
-    struct oc3_opcode opcode;        /* set/get OC-3 regs command opcode     */
-    u32               regs_haddr;    /* host DMA address of OC-3 regs buffer */
-} oc3_block_t;
-
-
-/* physical encoding statistics */
-
-typedef struct stats_phy {
-    __be32 crc_header_errors;    /* cells received with bad header CRC */
-    __be32 framing_errors;       /* cells received with bad framing    */
-    __be32 pad[ 2 ];             /* i960 padding                       */
-} stats_phy_t;
-
-
-/* OC-3 statistics */
-
-typedef struct stats_oc3 {
-    __be32 section_bip8_errors;    /* section 8 bit interleaved parity    */
-    __be32 path_bip8_errors;       /* path 8 bit interleaved parity       */
-    __be32 line_bip24_errors;      /* line 24 bit interleaved parity      */
-    __be32 line_febe_errors;       /* line far end block errors           */
-    __be32 path_febe_errors;       /* path far end block errors           */
-    __be32 corr_hcs_errors;        /* correctable header check sequence   */
-    __be32 ucorr_hcs_errors;       /* uncorrectable header check sequence */
-    __be32 pad[ 1 ];               /* i960 padding                        */
-} stats_oc3_t;
-
-
-/* ATM statistics */
-
-typedef struct stats_atm {
-    __be32	cells_transmitted;    /* cells transmitted                 */
-    __be32	cells_received;       /* cells received                    */
-    __be32	vpi_bad_range;        /* cell drops: VPI out of range      */
-    __be32	vpi_no_conn;          /* cell drops: no connection for VPI */
-    __be32	vci_bad_range;        /* cell drops: VCI out of range      */
-    __be32	vci_no_conn;          /* cell drops: no connection for VCI */
-    __be32	pad[ 2 ];             /* i960 padding                      */
-} stats_atm_t;
-
-/* AAL0 statistics */
-
-typedef struct stats_aal0 {
-    __be32	cells_transmitted;    /* cells transmitted */
-    __be32	cells_received;       /* cells received    */
-    __be32	cells_dropped;        /* cells dropped     */
-    __be32	pad[ 1 ];             /* i960 padding      */
-} stats_aal0_t;
-
-
-/* AAL3/4 statistics */
-
-typedef struct stats_aal34 {
-    __be32	cells_transmitted;         /* cells transmitted from segmented PDUs */
-    __be32	cells_received;            /* cells reassembled into PDUs           */
-    __be32	cells_crc_errors;          /* payload CRC error count               */
-    __be32	cells_protocol_errors;     /* SAR or CS layer protocol errors       */
-    __be32	cells_dropped;             /* cells dropped: partial reassembly     */
-    __be32	cspdus_transmitted;        /* CS PDUs transmitted                   */
-    __be32	cspdus_received;           /* CS PDUs received                      */
-    __be32	cspdus_protocol_errors;    /* CS layer protocol errors              */
-    __be32	cspdus_dropped;            /* reassembled PDUs drop'd (in cells)    */
-    __be32	pad[ 3 ];                  /* i960 padding                          */
-} stats_aal34_t;
-
-
-/* AAL5 statistics */
-
-typedef struct stats_aal5 {
-    __be32	cells_transmitted;         /* cells transmitted from segmented SDUs */
-    __be32	cells_received;		   /* cells reassembled into SDUs           */
-    __be32	cells_dropped;		   /* reassembled PDUs dropped (in cells)   */
-    __be32	congestion_experienced;    /* CRC error and length wrong            */
-    __be32	cspdus_transmitted;        /* CS PDUs transmitted                   */
-    __be32	cspdus_received;           /* CS PDUs received                      */
-    __be32	cspdus_crc_errors;         /* CS PDUs CRC errors                    */
-    __be32	cspdus_protocol_errors;    /* CS layer protocol errors              */
-    __be32	cspdus_dropped;            /* reassembled PDUs dropped              */
-    __be32	pad[ 3 ];                  /* i960 padding                          */
-} stats_aal5_t;
-
-
-/* auxiliary statistics */
-
-typedef struct stats_aux {
-    __be32	small_b1_failed;     /* receive BD allocation failures  */
-    __be32	large_b1_failed;     /* receive BD allocation failures  */
-    __be32	small_b2_failed;     /* receive BD allocation failures  */
-    __be32	large_b2_failed;     /* receive BD allocation failures  */
-    __be32	rpd_alloc_failed;    /* receive PDU allocation failures */
-    __be32	receive_carrier;     /* no carrier = 0, carrier = 1     */
-    __be32	pad[ 2 ];            /* i960 padding                    */
-} stats_aux_t;
-
-
-/* whole statistics buffer */
-
-typedef struct stats {
-    struct stats_phy   phy;      /* physical encoding statistics */
-    struct stats_oc3   oc3;      /* OC-3 statistics              */
-    struct stats_atm   atm;      /* ATM statistics               */
-    struct stats_aal0  aal0;     /* AAL0 statistics              */
-    struct stats_aal34 aal34;    /* AAL3/4 statistics            */
-    struct stats_aal5  aal5;     /* AAL5 statistics              */
-    struct stats_aux   aux;      /* auxiliary statistics         */
-} stats_t;
-
-
-/* get statistics command opcode */
-
-typedef struct stats_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} stats_opcode_t;
-
-
-/* get statistics command block */
-
-typedef struct stats_block {
-    struct stats_opcode opcode;         /* get statistics command opcode    */
-    u32                 stats_haddr;    /* host DMA address of stats buffer */
-} stats_block_t;
-
-
-/* expansion PROM data (PCI specific) */
-
-typedef struct prom_data {
-    u32 hw_revision;      /* hardware revision   */
-    u32 serial_number;    /* board serial number */
-    u8  mac_addr[ 8 ];    /* board MAC address   */
-} prom_data_t;
-
-
-/* get expansion PROM data command opcode */
-
-typedef struct prom_opcode {
-    BITFIELD2(
-        enum opcode opcode :  8,    /* cp opcode */
-        u32         pad    : 24     /* reserved  */
-    )
-} prom_opcode_t;
-
-
-/* get expansion PROM data command block */
-
-typedef struct prom_block {
-    struct prom_opcode opcode;        /* get PROM data command opcode    */
-    u32                prom_haddr;    /* host DMA address of PROM buffer */
-} prom_block_t;
-
-
-/* cp command */
-
-typedef union cmd {
-    enum   opcode           opcode;           /* operation code          */
-    struct activate_block   activate_block;   /* activate VC             */
-    struct deactivate_block deactivate_block; /* deactivate VC           */
-    struct stats_block      stats_block;      /* get statistics          */
-    struct prom_block       prom_block;       /* get expansion PROM data */
-    struct oc3_block        oc3_block;        /* get/set OC-3 registers  */
-    u32                     pad[ 4 ];         /* i960 padding            */
-} cmd_t;
-
-
-/* cp resident command queue */
-
-typedef struct cp_cmdq_entry {
-    union cmd cmd;             /* command                               */
-    u32       status_haddr;    /* host DMA address of completion status */
-    u32       pad[ 3 ];        /* i960 padding                          */
-} cp_cmdq_entry_t;
-
-
-/* host resident transmit queue entry */
-
-typedef struct host_txq_entry {
-    struct cp_txq_entry __iomem *cp_entry;    /* addr of cp resident tx queue entry       */
-    enum   status*          status;      /* addr of host resident status             */
-    struct tpd*             tpd;         /* addr of transmit PDU descriptor          */
-    u32                     tpd_dma;     /* DMA address of tpd                       */
-    struct sk_buff*         skb;         /* related skb                              */
-    void*                   data;        /* copy of misaligned data                  */
-    unsigned long           incarn;      /* vc_map incarnation when submitted for tx */
-    struct fore200e_vc_map* vc_map;
-
-} host_txq_entry_t;
-
-
-/* host resident receive queue entry */
-
-typedef struct host_rxq_entry {
-    struct cp_rxq_entry __iomem *cp_entry;    /* addr of cp resident rx queue entry */
-    enum   status*       status;      /* addr of host resident status       */
-    struct rpd*          rpd;         /* addr of receive PDU descriptor     */
-    u32                  rpd_dma;     /* DMA address of rpd                 */
-} host_rxq_entry_t;
-
-
-/* host resident buffer supply queue entry */
-
-typedef struct host_bsq_entry {
-    struct cp_bsq_entry __iomem *cp_entry;         /* addr of cp resident buffer supply queue entry */
-    enum   status*       status;           /* addr of host resident status                  */
-    struct rbd_block*    rbd_block;        /* addr of receive buffer descriptor block       */
-    u32                  rbd_block_dma;    /* DMA address od rdb                            */
-} host_bsq_entry_t;
-
-
-/* host resident command queue entry */
-
-typedef struct host_cmdq_entry {
-    struct cp_cmdq_entry __iomem *cp_entry;    /* addr of cp resident cmd queue entry */
-    enum status *status;	       /* addr of host resident status        */
-} host_cmdq_entry_t;
-
-
-/* chunk of memory */
-
-typedef struct chunk {
-    void* alloc_addr;    /* base address of allocated chunk */
-    void* align_addr;    /* base address of aligned chunk   */
-    dma_addr_t dma_addr; /* DMA address of aligned chunk    */
-    int   direction;     /* direction of DMA mapping        */
-    u32   alloc_size;    /* length of allocated chunk       */
-    u32   align_size;    /* length of aligned chunk         */
-} chunk_t;
-
-#define dma_size align_size             /* DMA useable size */
-
-
-/* host resident receive buffer */
-
-typedef struct buffer {
-    struct buffer*       next;        /* next receive buffer     */
-    enum   buffer_scheme scheme;      /* buffer scheme           */
-    enum   buffer_magn   magn;        /* buffer magnitude        */
-    struct chunk         data;        /* data buffer             */
-#ifdef FORE200E_BSQ_DEBUG
-    unsigned long        index;       /* buffer # in queue       */
-    int                  supplied;    /* 'buffer supplied' flag  */
-#endif
-} buffer_t;
-
-
-#if (BITS_PER_LONG == 32)
-#define FORE200E_BUF2HDL(buffer)    ((u32)(buffer))
-#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(handle))
-#else   /* deal with 64 bit pointers */
-#define FORE200E_BUF2HDL(buffer)    ((u32)((u64)(buffer)))
-#define FORE200E_HDL2BUF(handle)    ((struct buffer*)(((u64)(handle)) | PAGE_OFFSET))
-#endif
-
-
-/* host resident command queue */
-
-typedef struct host_cmdq {
-    struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ];    /* host resident cmd queue entries        */
-    int                    head;                            /* head of cmd queue                      */
-    struct chunk           status;                          /* array of completion status      */
-} host_cmdq_t;
-
-
-/* host resident transmit queue */
-
-typedef struct host_txq {
-    struct host_txq_entry host_entry[ QUEUE_SIZE_TX ];    /* host resident tx queue entries         */
-    int                   head;                           /* head of tx queue                       */
-    int                   tail;                           /* tail of tx queue                       */
-    struct chunk          tpd;                            /* array of tpds                          */
-    struct chunk          status;                         /* arry of completion status              */
-    int                   txing;                          /* number of pending PDUs in tx queue     */
-} host_txq_t;
-
-
-/* host resident receive queue */
-
-typedef struct host_rxq {
-    struct host_rxq_entry  host_entry[ QUEUE_SIZE_RX ];    /* host resident rx queue entries         */
-    int                    head;                           /* head of rx queue                       */
-    struct chunk           rpd;                            /* array of rpds                          */
-    struct chunk           status;                         /* array of completion status             */
-} host_rxq_t;
-
-
-/* host resident buffer supply queues */
-
-typedef struct host_bsq {
-    struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ];    /* host resident buffer supply queue entries */
-    int                   head;                           /* head of buffer supply queue               */
-    struct chunk          rbd_block;                      /* array of rbds                             */
-    struct chunk          status;                         /* array of completion status                */
-    struct buffer*        buffer;                         /* array of rx buffers                       */
-    struct buffer*        freebuf;                        /* list of free rx buffers                   */
-    volatile int          freebuf_count;                  /* count of free rx buffers                  */
-} host_bsq_t;
-
-
-/* header of the firmware image */
-
-typedef struct fw_header {
-    __le32 magic;           /* magic number                               */
-    __le32 version;         /* firmware version id                        */
-    __le32 load_offset;     /* fw load offset in board memory             */
-    __le32 start_offset;    /* fw execution start address in board memory */
-} fw_header_t;
-
-#define FW_HEADER_MAGIC  0x65726f66    /* 'fore' */
-
-
-/* receive buffer supply queues scheme specification */
-
-typedef struct bs_spec {
-    u32	queue_length;      /* queue capacity                     */
-    u32	buffer_size;	   /* host buffer size			 */
-    u32	pool_size;	   /* number of rbds			 */
-    u32	supply_blksize;    /* num of rbds in I/O block (multiple
-			      of 4 between 4 and 124 inclusive)	 */
-} bs_spec_t;
-
-
-/* initialization command block (one-time command, not in cmd queue) */
-
-typedef struct init_block {
-    enum opcode  opcode;               /* initialize command             */
-    enum status	 status;	       /* related status word            */
-    u32          receive_threshold;    /* not used                       */
-    u32          num_connect;          /* ATM connections                */
-    u32          cmd_queue_len;        /* length of command queue        */
-    u32          tx_queue_len;         /* length of transmit queue       */
-    u32          rx_queue_len;         /* length of receive queue        */
-    u32          rsd_extension;        /* number of extra 32 byte blocks */
-    u32          tsd_extension;        /* number of extra 32 byte blocks */
-    u32          conless_vpvc;         /* not used                       */
-    u32          pad[ 2 ];             /* force quad alignment           */
-    struct bs_spec bs_spec[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];      /* buffer supply queues spec */
-} init_block_t;
-
-
-typedef enum media_type {
-    MEDIA_TYPE_CAT5_UTP  = 0x06,    /* unshielded twisted pair */
-    MEDIA_TYPE_MM_OC3_ST = 0x16,    /* multimode fiber ST      */
-    MEDIA_TYPE_MM_OC3_SC = 0x26,    /* multimode fiber SC      */
-    MEDIA_TYPE_SM_OC3_ST = 0x36,    /* single-mode fiber ST    */
-    MEDIA_TYPE_SM_OC3_SC = 0x46     /* single-mode fiber SC    */
-} media_type_t;
-
-#define FORE200E_MEDIA_INDEX(media_type)   ((media_type)>>4)
-
-
-/* cp resident queues */
-
-typedef struct cp_queues {
-    u32	              cp_cmdq;         /* command queue                      */
-    u32	              cp_txq;          /* transmit queue                     */
-    u32	              cp_rxq;          /* receive queue                      */
-    u32               cp_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];        /* buffer supply queues */
-    u32	              imask;             /* 1 enables cp to host interrupts  */
-    u32	              istat;             /* 1 for interrupt posted           */
-    u32	              heap_base;         /* offset form beginning of ram     */
-    u32	              heap_size;         /* space available for queues       */
-    u32	              hlogger;           /* non zero for host logging        */
-    u32               heartbeat;         /* cp heartbeat                     */
-    u32	              fw_release;        /* firmware version                 */
-    u32	              mon960_release;    /* i960 monitor version             */
-    u32	              tq_plen;           /* transmit throughput measurements */
-    /* make sure the init block remains on a quad word boundary              */
-    struct init_block init;              /* one time cmd, not in cmd queue   */
-    enum   media_type media_type;        /* media type id                    */
-    u32               oc3_revision;      /* OC-3 revision number             */
-} cp_queues_t;
-
-
-/* boot status */
-
-typedef enum boot_status {
-    BSTAT_COLD_START    = (u32) 0xc01dc01d,    /* cold start              */
-    BSTAT_SELFTEST_OK   = (u32) 0x02201958,    /* self-test ok            */
-    BSTAT_SELFTEST_FAIL = (u32) 0xadbadbad,    /* self-test failed        */
-    BSTAT_CP_RUNNING    = (u32) 0xce11feed,    /* cp is running           */
-    BSTAT_MON_TOO_BIG   = (u32) 0x10aded00     /* i960 monitor is too big */
-} boot_status_t;
-
-
-/* software UART */
-
-typedef struct soft_uart {
-    u32 send;    /* write register */
-    u32 recv;    /* read register  */
-} soft_uart_t;
-
-#define FORE200E_CP_MONITOR_UART_FREE     0x00000000
-#define FORE200E_CP_MONITOR_UART_AVAIL    0x01000000
-
-
-/* i960 monitor */
-
-typedef struct cp_monitor {
-    struct soft_uart    soft_uart;      /* software UART           */
-    enum boot_status	bstat;          /* boot status             */
-    u32			app_base;       /* application base offset */
-    u32			mon_version;    /* i960 monitor version    */
-} cp_monitor_t;
-
-
-/* device state */
-
-typedef enum fore200e_state {
-    FORE200E_STATE_BLANK,         /* initial state                     */
-    FORE200E_STATE_REGISTER,      /* device registered                 */
-    FORE200E_STATE_CONFIGURE,     /* bus interface configured          */
-    FORE200E_STATE_MAP,           /* board space mapped in host memory */
-    FORE200E_STATE_RESET,         /* board resetted                    */
-    FORE200E_STATE_START_FW,      /* firmware started                  */
-    FORE200E_STATE_INITIALIZE,    /* initialize command successful     */
-    FORE200E_STATE_INIT_CMDQ,     /* command queue initialized         */
-    FORE200E_STATE_INIT_TXQ,      /* transmit queue initialized        */
-    FORE200E_STATE_INIT_RXQ,      /* receive queue initialized         */
-    FORE200E_STATE_INIT_BSQ,      /* buffer supply queue initialized   */
-    FORE200E_STATE_ALLOC_BUF,     /* receive buffers allocated         */
-    FORE200E_STATE_IRQ,           /* host interrupt requested          */
-    FORE200E_STATE_COMPLETE       /* initialization completed          */
-} fore200e_state;
-
-
-/* PCA-200E registers */
-
-typedef struct fore200e_pca_regs {
-    volatile u32 __iomem * hcr;    /* address of host control register        */
-    volatile u32 __iomem * imr;    /* address of host interrupt mask register */
-    volatile u32 __iomem * psr;    /* address of PCI specific register        */
-} fore200e_pca_regs_t;
-
-
-/* SBA-200E registers */
-
-typedef struct fore200e_sba_regs {
-    u32 __iomem *hcr;    /* address of host control register              */
-    u32 __iomem *bsr;    /* address of burst transfer size register       */
-    u32 __iomem *isr;    /* address of interrupt level selection register */
-} fore200e_sba_regs_t;
-
-
-/* model-specific registers */
-
-typedef union fore200e_regs {
-    struct fore200e_pca_regs pca;    /* PCA-200E registers */
-    struct fore200e_sba_regs sba;    /* SBA-200E registers */
-} fore200e_regs;
-
-
-struct fore200e;
-
-/* bus-dependent data */
-
-typedef struct fore200e_bus {
-    char*                model_name;          /* board model name                       */
-    char*                proc_name;           /* board name under /proc/atm             */
-    int                  descr_alignment;     /* tpd/rpd/rbd DMA alignment requirement  */
-    int                  buffer_alignment;    /* rx buffers DMA alignment requirement   */
-    int                  status_alignment;    /* status words DMA alignment requirement */
-    u32                  (*read)(volatile u32 __iomem *);
-    void                 (*write)(u32, volatile u32 __iomem *);
-    int                  (*configure)(struct fore200e*); 
-    int                  (*map)(struct fore200e*); 
-    void                 (*reset)(struct fore200e*);
-    int                  (*prom_read)(struct fore200e*, struct prom_data*);
-    void                 (*unmap)(struct fore200e*);
-    void                 (*irq_enable)(struct fore200e*);
-    int                  (*irq_check)(struct fore200e*);
-    void                 (*irq_ack)(struct fore200e*);
-    int                  (*proc_read)(struct fore200e*, char*);
-} fore200e_bus_t;
-
-/* vc mapping */
-
-typedef struct fore200e_vc_map {
-    struct atm_vcc* vcc;       /* vcc entry              */
-    unsigned long   incarn;    /* vcc incarnation number */
-} fore200e_vc_map_t;
-
-#define FORE200E_VC_MAP(fore200e, vpi, vci)  \
-        (& (fore200e)->vc_map[ ((vpi) << FORE200E_VCI_BITS) | (vci) ])
-
-
-/* per-device data */
-
-typedef struct fore200e {
-    const struct fore200e_bus* bus;                    /* bus-dependent code and data        */
-    union        fore200e_regs regs;                   /* bus-dependent registers            */
-    struct       atm_dev*      atm_dev;                /* ATM device                         */
-
-    enum fore200e_state        state;                  /* device state                       */
-
-    char                       name[16];               /* device name                        */
-    struct device	       *dev;
-    int                        irq;                    /* irq number                         */
-    unsigned long              phys_base;              /* physical base address              */
-    void __iomem *             virt_base;              /* virtual base address               */
-    
-    unsigned char              esi[ ESI_LEN ];         /* end system identifier              */
-
-    struct cp_monitor __iomem *         cp_monitor;    /* i960 monitor address               */
-    struct cp_queues __iomem *          cp_queues;              /* cp resident queues                 */
-    struct host_cmdq           host_cmdq;              /* host resident cmd queue            */
-    struct host_txq            host_txq;               /* host resident tx queue             */
-    struct host_rxq            host_rxq;               /* host resident rx queue             */
-                                                       /* host resident buffer supply queues */
-    struct host_bsq            host_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];       
-
-    u32                        available_cell_rate;    /* remaining pseudo-CBR bw on link    */
-
-    int                        loop_mode;              /* S/UNI loopback mode                */
-
-    struct stats*              stats;                  /* last snapshot of the stats         */
-    
-    struct mutex               rate_mtx;               /* protects rate reservation ops      */
-    spinlock_t                 q_lock;                 /* protects queue ops                 */
-#ifdef FORE200E_USE_TASKLET
-    struct tasklet_struct      tx_tasklet;             /* performs tx interrupt work         */
-    struct tasklet_struct      rx_tasklet;             /* performs rx interrupt work         */
-#endif
-    unsigned long              tx_sat;                 /* tx queue saturation count          */
-
-    unsigned long              incarn_count;
-    struct fore200e_vc_map     vc_map[ NBR_CONNECT ];  /* vc mapping                         */
-} fore200e_t;
-
-
-/* per-vcc data */
-
-typedef struct fore200e_vcc {
-    enum buffer_scheme     scheme;             /* rx buffer scheme                   */
-    struct tpd_rate        rate;               /* tx rate control data               */
-    int                    rx_min_pdu;         /* size of smallest PDU received      */
-    int                    rx_max_pdu;         /* size of largest PDU received       */
-    int                    tx_min_pdu;         /* size of smallest PDU transmitted   */
-    int                    tx_max_pdu;         /* size of largest PDU transmitted    */
-    unsigned long          tx_pdu;             /* nbr of tx pdus                     */
-    unsigned long          rx_pdu;             /* nbr of rx pdus                     */
-} fore200e_vcc_t;
-
-
-
-/* 200E-series common memory layout */
-
-#define FORE200E_CP_MONITOR_OFFSET	0x00000400    /* i960 monitor interface */
-#define FORE200E_CP_QUEUES_OFFSET	0x00004d40    /* cp resident queues     */
-
-
-/* PCA-200E memory layout */
-
-#define PCA200E_IOSPACE_LENGTH	        0x00200000
-
-#define PCA200E_HCR_OFFSET		0x00100000    /* board control register */
-#define PCA200E_IMR_OFFSET		0x00100004    /* host IRQ mask register */
-#define PCA200E_PSR_OFFSET		0x00100008    /* PCI specific register  */
-
-
-/* PCA-200E host control register */
-
-#define PCA200E_HCR_RESET     (1<<0)    /* read / write */
-#define PCA200E_HCR_HOLD_LOCK (1<<1)    /* read / write */
-#define PCA200E_HCR_I960FAIL  (1<<2)    /* read         */
-#define PCA200E_HCR_INTRB     (1<<2)    /* write        */
-#define PCA200E_HCR_HOLD_ACK  (1<<3)    /* read         */
-#define PCA200E_HCR_INTRA     (1<<3)    /* write        */
-#define PCA200E_HCR_OUTFULL   (1<<4)    /* read         */
-#define PCA200E_HCR_CLRINTR   (1<<4)    /* write        */
-#define PCA200E_HCR_ESPHOLD   (1<<5)    /* read         */
-#define PCA200E_HCR_INFULL    (1<<6)    /* read         */
-#define PCA200E_HCR_TESTMODE  (1<<7)    /* read         */
-
-
-/* PCA-200E PCI bus interface regs (offsets in PCI config space) */
-
-#define PCA200E_PCI_LATENCY      0x40    /* maximum slave latenty            */
-#define PCA200E_PCI_MASTER_CTRL  0x41    /* master control                   */
-#define PCA200E_PCI_THRESHOLD    0x42    /* burst / continuous req threshold  */
-
-/* PBI master control register */
-
-#define PCA200E_CTRL_DIS_CACHE_RD      (1<<0)    /* disable cache-line reads                         */
-#define PCA200E_CTRL_DIS_WRT_INVAL     (1<<1)    /* disable writes and invalidates                   */
-#define PCA200E_CTRL_2_CACHE_WRT_INVAL (1<<2)    /* require 2 cache-lines for writes and invalidates */
-#define PCA200E_CTRL_IGN_LAT_TIMER     (1<<3)    /* ignore the latency timer                         */
-#define PCA200E_CTRL_ENA_CONT_REQ_MODE (1<<4)    /* enable continuous request mode                   */
-#define PCA200E_CTRL_LARGE_PCI_BURSTS  (1<<5)    /* force large PCI bus bursts                       */
-#define PCA200E_CTRL_CONVERT_ENDIAN    (1<<6)    /* convert endianess of slave RAM accesses          */
-
-
-
-#define SBA200E_PROM_NAME  "FORE,sba-200e"    /* device name in openprom tree */
-
-
-/* size of SBA-200E registers */
-
-#define SBA200E_HCR_LENGTH        4
-#define SBA200E_BSR_LENGTH        4
-#define SBA200E_ISR_LENGTH        4
-#define SBA200E_RAM_LENGTH  0x40000
-
-
-/* SBA-200E SBUS burst transfer size register */
-
-#define SBA200E_BSR_BURST4   0x04
-#define SBA200E_BSR_BURST8   0x08
-#define SBA200E_BSR_BURST16  0x10
-
-
-/* SBA-200E host control register */
-
-#define SBA200E_HCR_RESET        (1<<0)    /* read / write (sticky) */
-#define SBA200E_HCR_HOLD_LOCK    (1<<1)    /* read / write (sticky) */
-#define SBA200E_HCR_I960FAIL     (1<<2)    /* read                  */
-#define SBA200E_HCR_I960SETINTR  (1<<2)    /* write                 */
-#define SBA200E_HCR_OUTFULL      (1<<3)    /* read                  */
-#define SBA200E_HCR_INTR_CLR     (1<<3)    /* write                 */
-#define SBA200E_HCR_INTR_ENA     (1<<4)    /* read / write (sticky) */
-#define SBA200E_HCR_ESPHOLD      (1<<5)    /* read                  */
-#define SBA200E_HCR_INFULL       (1<<6)    /* read                  */
-#define SBA200E_HCR_TESTMODE     (1<<7)    /* read                  */
-#define SBA200E_HCR_INTR_REQ     (1<<8)    /* read                  */
-
-#define SBA200E_HCR_STICKY       (SBA200E_HCR_RESET | SBA200E_HCR_HOLD_LOCK | SBA200E_HCR_INTR_ENA)
-
-
-#endif /* __KERNEL__ */
-#endif /* _FORE200E_H */
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
deleted file mode 100644
index bb9cb00f..0000000
--- a/drivers/atm/he.c
+++ /dev/null
@@ -1,2861 +0,0 @@
-/*
-
-  he.c
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/*
-
-  he.c
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  Permission to use, copy, modify and distribute this software and its
-  documentation is hereby granted, provided that both the copyright
-  notice and this permission notice appear in all copies of the software,
-  derivative works or modified versions, and any portions thereof, and
-  that both notices appear in supporting documentation.
-
-  NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
-  DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
-  RESULTING FROM THE USE OF THIS SOFTWARE.
-
-  This driver was written using the "Programmer's Reference Manual for
-  ForeRunnerHE(tm)", MANU0361-01 - Rev. A, 08/21/98.
-
-  AUTHORS:
-	chas williams <chas@cmf.nrl.navy.mil>
-	eric kinzie <ekinzie@cmf.nrl.navy.mil>
-
-  NOTES:
-	4096 supported 'connections'
-	group 0 is used for all traffic
-	interrupt queue 0 is used for all interrupts
-	aal0 support (based on work from ulrich.u.muller@nokia.com)
-
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/bitmap.h>
-#include <linux/slab.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/uaccess.h>
-
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/sonet.h>
-
-#undef USE_SCATTERGATHER
-#undef USE_CHECKSUM_HW			/* still confused about this */
-/* #undef HE_DEBUG */
-
-#include "he.h"
-#include "suni.h"
-#include <linux/atm_he.h>
-
-#define hprintk(fmt,args...)	printk(KERN_ERR DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-
-#ifdef HE_DEBUG
-#define HPRINTK(fmt,args...)	printk(KERN_DEBUG DEV_LABEL "%d: " fmt, he_dev->number , ##args)
-#else /* !HE_DEBUG */
-#define HPRINTK(fmt,args...)	do { } while (0)
-#endif /* HE_DEBUG */
-
-/* declarations */
-
-static int he_open(struct atm_vcc *vcc);
-static void he_close(struct atm_vcc *vcc);
-static int he_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int he_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg);
-static irqreturn_t he_irq_handler(int irq, void *dev_id);
-static void he_tasklet(unsigned long data);
-static int he_proc_read(struct atm_dev *dev,loff_t *pos,char *page);
-static int he_start(struct atm_dev *dev);
-static void he_stop(struct he_dev *dev);
-static void he_phy_put(struct atm_dev *, unsigned char, unsigned long);
-static unsigned char he_phy_get(struct atm_dev *, unsigned long);
-
-static u8 read_prom_byte(struct he_dev *he_dev, int addr);
-
-/* globals */
-
-static struct he_dev *he_devs;
-static bool disable64;
-static short nvpibits = -1;
-static short nvcibits = -1;
-static short rx_skb_reserve = 16;
-static bool irq_coalesce = true;
-static bool sdh;
-
-/* Read from EEPROM = 0000 0011b */
-static unsigned int readtab[] = {
-	CS_HIGH | CLK_HIGH,
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW,
-	CLK_HIGH,               /* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,     /* 1 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH      /* 1 */
-};     
- 
-/* Clock to read from/write to the EEPROM */
-static unsigned int clocktab[] = {
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW
-};     
-
-static const struct atmdev_ops he_ops =
-{
-	.open =		he_open,
-	.close =	he_close,	
-	.ioctl =	he_ioctl,	
-	.send =		he_send,
-	.phy_put =	he_phy_put,
-	.phy_get =	he_phy_get,
-	.proc_read =	he_proc_read,
-	.owner =	THIS_MODULE
-};
-
-#define he_writel(dev, val, reg)	do { writel(val, (dev)->membase + (reg)); wmb(); } while (0)
-#define he_readl(dev, reg)		readl((dev)->membase + (reg))
-
-/* section 2.12 connection memory access */
-
-static __inline__ void
-he_writel_internal(struct he_dev *he_dev, unsigned val, unsigned addr,
-								unsigned flags)
-{
-	he_writel(he_dev, val, CON_DAT);
-	(void) he_readl(he_dev, CON_DAT);		/* flush posted writes */
-	he_writel(he_dev, flags | CON_CTL_WRITE | CON_CTL_ADDR(addr), CON_CTL);
-	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
-}
-
-#define he_writel_rcm(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_RCM)
-
-#define he_writel_tcm(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_TCM)
-
-#define he_writel_mbox(dev, val, reg) 				\
-			he_writel_internal(dev, val, reg, CON_CTL_MBOX)
-
-static unsigned
-he_readl_internal(struct he_dev *he_dev, unsigned addr, unsigned flags)
-{
-	he_writel(he_dev, flags | CON_CTL_READ | CON_CTL_ADDR(addr), CON_CTL);
-	while (he_readl(he_dev, CON_CTL) & CON_CTL_BUSY);
-	return he_readl(he_dev, CON_DAT);
-}
-
-#define he_readl_rcm(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_RCM)
-
-#define he_readl_tcm(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_TCM)
-
-#define he_readl_mbox(dev, reg) \
-			he_readl_internal(dev, reg, CON_CTL_MBOX)
-
-
-/* figure 2.2 connection id */
-
-#define he_mkcid(dev, vpi, vci)		(((vpi << (dev)->vcibits) | vci) & 0x1fff)
-
-/* 2.5.1 per connection transmit state registers */
-
-#define he_writel_tsr0(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 0)
-#define he_readl_tsr0(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 0)
-
-#define he_writel_tsr1(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 1)
-
-#define he_writel_tsr2(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 2)
-
-#define he_writel_tsr3(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 3)
-
-#define he_writel_tsr4(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 4)
-
-	/* from page 2-20
-	 *
-	 * NOTE While the transmit connection is active, bits 23 through 0
-	 *      of this register must not be written by the host.  Byte
-	 *      enables should be used during normal operation when writing
-	 *      the most significant byte.
-	 */
-
-#define he_writel_tsr4_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRA | (cid << 3) | 4, \
-							CON_CTL_TCM \
-							| CON_BYTE_DISABLE_2 \
-							| CON_BYTE_DISABLE_1 \
-							| CON_BYTE_DISABLE_0)
-
-#define he_readl_tsr4(dev, cid) \
-		he_readl_tcm(dev, CONFIG_TSRA | (cid << 3) | 4)
-
-#define he_writel_tsr5(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 5)
-
-#define he_writel_tsr6(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 6)
-
-#define he_writel_tsr7(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRA | (cid << 3) | 7)
-
-
-#define he_writel_tsr8(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 0)
-
-#define he_writel_tsr9(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 1)
-
-#define he_writel_tsr10(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 2)
-
-#define he_writel_tsr11(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRB | (cid << 2) | 3)
-
-
-#define he_writel_tsr12(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 0)
-
-#define he_writel_tsr13(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRC | (cid << 1) | 1)
-
-
-#define he_writel_tsr14(dev, val, cid) \
-		he_writel_tcm(dev, val, CONFIG_TSRD | cid)
-
-#define he_writel_tsr14_upper(dev, val, cid) \
-		he_writel_internal(dev, val, CONFIG_TSRD | cid, \
-							CON_CTL_TCM \
-							| CON_BYTE_DISABLE_2 \
-							| CON_BYTE_DISABLE_1 \
-							| CON_BYTE_DISABLE_0)
-
-/* 2.7.1 per connection receive state registers */
-
-#define he_writel_rsr0(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 0)
-#define he_readl_rsr0(dev, cid) \
-		he_readl_rcm(dev, 0x00000 | (cid << 3) | 0)
-
-#define he_writel_rsr1(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 1)
-
-#define he_writel_rsr2(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 2)
-
-#define he_writel_rsr3(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 3)
-
-#define he_writel_rsr4(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 4)
-
-#define he_writel_rsr5(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 5)
-
-#define he_writel_rsr6(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 6)
-
-#define he_writel_rsr7(dev, val, cid) \
-		he_writel_rcm(dev, val, 0x00000 | (cid << 3) | 7)
-
-static __inline__ struct atm_vcc*
-__find_vcc(struct he_dev *he_dev, unsigned cid)
-{
-	struct hlist_head *head;
-	struct atm_vcc *vcc;
-	struct sock *s;
-	short vpi;
-	int vci;
-
-	vpi = cid >> he_dev->vcibits;
-	vci = cid & ((1 << he_dev->vcibits) - 1);
-	head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
-
-	sk_for_each(s, head) {
-		vcc = atm_sk(s);
-		if (vcc->dev == he_dev->atm_dev &&
-		    vcc->vci == vci && vcc->vpi == vpi &&
-		    vcc->qos.rxtp.traffic_class != ATM_NONE) {
-				return vcc;
-		}
-	}
-	return NULL;
-}
-
-static int he_init_one(struct pci_dev *pci_dev,
-		       const struct pci_device_id *pci_ent)
-{
-	struct atm_dev *atm_dev = NULL;
-	struct he_dev *he_dev = NULL;
-	int err = 0;
-
-	printk(KERN_INFO "ATM he driver\n");
-
-	if (pci_enable_device(pci_dev))
-		return -EIO;
-	if (dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32)) != 0) {
-		printk(KERN_WARNING "he: no suitable dma available\n");
-		err = -EIO;
-		goto init_one_failure;
-	}
-
-	atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL);
-	if (!atm_dev) {
-		err = -ENODEV;
-		goto init_one_failure;
-	}
-	pci_set_drvdata(pci_dev, atm_dev);
-
-	he_dev = kzalloc_obj(struct he_dev);
-	if (!he_dev) {
-		err = -ENOMEM;
-		goto init_one_failure;
-	}
-	he_dev->pci_dev = pci_dev;
-	he_dev->atm_dev = atm_dev;
-	he_dev->atm_dev->dev_data = he_dev;
-	atm_dev->dev_data = he_dev;
-	he_dev->number = atm_dev->number;
-	tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev);
-	spin_lock_init(&he_dev->global_lock);
-
-	if (he_start(atm_dev)) {
-		he_stop(he_dev);
-		err = -ENODEV;
-		goto init_one_failure;
-	}
-	he_dev->next = NULL;
-	if (he_devs)
-		he_dev->next = he_devs;
-	he_devs = he_dev;
-	return 0;
-
-init_one_failure:
-	if (atm_dev)
-		atm_dev_deregister(atm_dev);
-	kfree(he_dev);
-	pci_disable_device(pci_dev);
-	return err;
-}
-
-static void he_remove_one(struct pci_dev *pci_dev)
-{
-	struct atm_dev *atm_dev;
-	struct he_dev *he_dev;
-
-	atm_dev = pci_get_drvdata(pci_dev);
-	he_dev = HE_DEV(atm_dev);
-
-	/* need to remove from he_devs */
-
-	he_stop(he_dev);
-	atm_dev_deregister(atm_dev);
-	kfree(he_dev);
-
-	pci_disable_device(pci_dev);
-}
-
-
-static unsigned
-rate_to_atmf(unsigned rate)		/* cps to atm forum format */
-{
-#define NONZERO (1 << 14)
-
-	unsigned exp = 0;
-
-	if (rate == 0)
-		return 0;
-
-	rate <<= 9;
-	while (rate > 0x3ff) {
-		++exp;
-		rate >>= 1;
-	}
-
-	return (NONZERO | (exp << 9) | (rate & 0x1ff));
-}
-
-static void he_init_rx_lbfp0(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->r0_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = 0;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA);
-
-	he_writel(he_dev, lbufd_index, RLBF0_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->r0_numbuffs; ++i) {
-		lbufd_index += 2;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 4;
-	}
-		
-	he_writel(he_dev, lbufd_index - 2, RLBF0_T);
-	he_writel(he_dev, he_dev->r0_numbuffs, RLBF0_C);
-}
-
-static void he_init_rx_lbfp1(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->r1_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = 1;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
-
-	he_writel(he_dev, lbufd_index, RLBF1_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->r1_numbuffs; ++i) {
-		lbufd_index += 2;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 4;
-	}
-		
-	he_writel(he_dev, lbufd_index - 2, RLBF1_T);
-	he_writel(he_dev, he_dev->r1_numbuffs, RLBF1_C);
-}
-
-static void he_init_tx_lbfp(struct he_dev *he_dev)
-{
-	unsigned i, lbm_offset, lbufd_index, lbuf_addr, lbuf_count;
-	unsigned lbufs_per_row = he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	unsigned lbuf_bufsize = he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD;
-	unsigned row_offset = he_dev->tx_startrow * he_dev->bytes_per_row;
-	
-	lbufd_index = he_dev->r0_numbuffs + he_dev->r1_numbuffs;
-	lbm_offset = he_readl(he_dev, RCMLBM_BA) + (2 * lbufd_index);
-
-	he_writel(he_dev, lbufd_index, TLBF_H);
-
-	for (i = 0, lbuf_count = 0; i < he_dev->tx_numbuffs; ++i) {
-		lbufd_index += 1;
-		lbuf_addr = (row_offset + (lbuf_count * lbuf_bufsize)) / 32;
-
-		he_writel_rcm(he_dev, lbuf_addr, lbm_offset);
-		he_writel_rcm(he_dev, lbufd_index, lbm_offset + 1);
-
-		if (++lbuf_count == lbufs_per_row) {
-			lbuf_count = 0;
-			row_offset += he_dev->bytes_per_row;
-		}
-		lbm_offset += 2;
-	}
-		
-	he_writel(he_dev, lbufd_index - 1, TLBF_T);
-}
-
-static int he_init_tpdrq(struct he_dev *he_dev)
-{
-	he_dev->tpdrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-						CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq),
-						&he_dev->tpdrq_phys,
-						GFP_KERNEL);
-	if (he_dev->tpdrq_base == NULL) {
-		hprintk("failed to alloc tpdrq\n");
-		return -ENOMEM;
-	}
-
-	he_dev->tpdrq_tail = he_dev->tpdrq_base;
-	he_dev->tpdrq_head = he_dev->tpdrq_base;
-
-	he_writel(he_dev, he_dev->tpdrq_phys, TPDRQ_B_H);
-	he_writel(he_dev, 0, TPDRQ_T);	
-	he_writel(he_dev, CONFIG_TPDRQ_SIZE - 1, TPDRQ_S);
-
-	return 0;
-}
-
-static void he_init_cs_block(struct he_dev *he_dev)
-{
-	unsigned clock, rate, delta;
-	int reg;
-
-	/* 5.1.7 cs block initialization */
-
-	for (reg = 0; reg < 0x20; ++reg)
-		he_writel_mbox(he_dev, 0x0, CS_STTIM0 + reg);
-
-	/* rate grid timer reload values */
-
-	clock = he_is622(he_dev) ? 66667000 : 50000000;
-	rate = he_dev->atm_dev->link_rate;
-	delta = rate / 16 / 2;
-
-	for (reg = 0; reg < 0x10; ++reg) {
-		/* 2.4 internal transmit function
-		 *
-	 	 * we initialize the first row in the rate grid.
-		 * values are period (in clock cycles) of timer
-		 */
-		unsigned period = clock / rate;
-
-		he_writel_mbox(he_dev, period, CS_TGRLD0 + reg);
-		rate -= delta;
-	}
-
-	if (he_is622(he_dev)) {
-		/* table 5.2 (4 cells per lbuf) */
-		he_writel_mbox(he_dev, 0x000800fa, CS_ERTHR0);
-		he_writel_mbox(he_dev, 0x000c33cb, CS_ERTHR1);
-		he_writel_mbox(he_dev, 0x0010101b, CS_ERTHR2);
-		he_writel_mbox(he_dev, 0x00181dac, CS_ERTHR3);
-		he_writel_mbox(he_dev, 0x00280600, CS_ERTHR4);
-
-		/* table 5.3, 5.4, 5.5, 5.6, 5.7 */
-		he_writel_mbox(he_dev, 0x023de8b3, CS_ERCTL0);
-		he_writel_mbox(he_dev, 0x1801, CS_ERCTL1);
-		he_writel_mbox(he_dev, 0x68b3, CS_ERCTL2);
-		he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0);
-		he_writel_mbox(he_dev, 0x68b3, CS_ERSTAT1);
-		he_writel_mbox(he_dev, 0x14585, CS_RTFWR);
-
-		he_writel_mbox(he_dev, 0x4680, CS_RTATR);
-
-		/* table 5.8 */
-		he_writel_mbox(he_dev, 0x00159ece, CS_TFBSET);
-		he_writel_mbox(he_dev, 0x68b3, CS_WCRMAX);
-		he_writel_mbox(he_dev, 0x5eb3, CS_WCRMIN);
-		he_writel_mbox(he_dev, 0xe8b3, CS_WCRINC);
-		he_writel_mbox(he_dev, 0xdeb3, CS_WCRDEC);
-		he_writel_mbox(he_dev, 0x68b3, CS_WCRCEIL);
-
-		/* table 5.9 */
-		he_writel_mbox(he_dev, 0x5, CS_OTPPER);
-		he_writel_mbox(he_dev, 0x14, CS_OTWPER);
-	} else {
-		/* table 5.1 (4 cells per lbuf) */
-		he_writel_mbox(he_dev, 0x000400ea, CS_ERTHR0);
-		he_writel_mbox(he_dev, 0x00063388, CS_ERTHR1);
-		he_writel_mbox(he_dev, 0x00081018, CS_ERTHR2);
-		he_writel_mbox(he_dev, 0x000c1dac, CS_ERTHR3);
-		he_writel_mbox(he_dev, 0x0014051a, CS_ERTHR4);
-
-		/* table 5.3, 5.4, 5.5, 5.6, 5.7 */
-		he_writel_mbox(he_dev, 0x0235e4b1, CS_ERCTL0);
-		he_writel_mbox(he_dev, 0x4701, CS_ERCTL1);
-		he_writel_mbox(he_dev, 0x64b1, CS_ERCTL2);
-		he_writel_mbox(he_dev, 0x1280, CS_ERSTAT0);
-		he_writel_mbox(he_dev, 0x64b1, CS_ERSTAT1);
-		he_writel_mbox(he_dev, 0xf424, CS_RTFWR);
-
-		he_writel_mbox(he_dev, 0x4680, CS_RTATR);
-
-		/* table 5.8 */
-		he_writel_mbox(he_dev, 0x000563b7, CS_TFBSET);
-		he_writel_mbox(he_dev, 0x64b1, CS_WCRMAX);
-		he_writel_mbox(he_dev, 0x5ab1, CS_WCRMIN);
-		he_writel_mbox(he_dev, 0xe4b1, CS_WCRINC);
-		he_writel_mbox(he_dev, 0xdab1, CS_WCRDEC);
-		he_writel_mbox(he_dev, 0x64b1, CS_WCRCEIL);
-
-		/* table 5.9 */
-		he_writel_mbox(he_dev, 0x6, CS_OTPPER);
-		he_writel_mbox(he_dev, 0x1e, CS_OTWPER);
-	}
-
-	he_writel_mbox(he_dev, 0x8, CS_OTTLIM);
-
-	for (reg = 0; reg < 0x8; ++reg)
-		he_writel_mbox(he_dev, 0x0, CS_HGRRT0 + reg);
-
-}
-
-static int he_init_cs_block_rcm(struct he_dev *he_dev)
-{
-	unsigned (*rategrid)[16][16];
-	unsigned rate, delta;
-	int i, j, reg;
-
-	unsigned rate_atmf, exp, man;
-	unsigned long long rate_cps;
-	int mult, buf, buf_limit = 4;
-
-	rategrid = kmalloc( sizeof(unsigned) * 16 * 16, GFP_KERNEL);
-	if (!rategrid)
-		return -ENOMEM;
-
-	/* initialize rate grid group table */
-
-	for (reg = 0x0; reg < 0xff; ++reg)
-		he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg);
-
-	/* initialize rate controller groups */
-
-	for (reg = 0x100; reg < 0x1ff; ++reg)
-		he_writel_rcm(he_dev, 0x0, CONFIG_RCMABR + reg);
-	
-	/* initialize tNrm lookup table */
-
-	/* the manual makes reference to a routine in a sample driver
-	   for proper configuration; fortunately, we only need this
-	   in order to support abr connection */
-	
-	/* initialize rate to group table */
-
-	rate = he_dev->atm_dev->link_rate;
-	delta = rate / 32;
-
-	/*
-	 * 2.4 transmit internal functions
-	 * 
-	 * we construct a copy of the rate grid used by the scheduler
-	 * in order to construct the rate to group table below
-	 */
-
-	for (j = 0; j < 16; j++) {
-		(*rategrid)[0][j] = rate;
-		rate -= delta;
-	}
-
-	for (i = 1; i < 16; i++)
-		for (j = 0; j < 16; j++)
-			if (i > 14)
-				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 4;
-			else
-				(*rategrid)[i][j] = (*rategrid)[i - 1][j] / 2;
-
-	/*
-	 * 2.4 transmit internal function
-	 *
-	 * this table maps the upper 5 bits of exponent and mantissa
-	 * of the atm forum representation of the rate into an index
-	 * on rate grid  
-	 */
-
-	rate_atmf = 0;
-	while (rate_atmf < 0x400) {
-		man = (rate_atmf & 0x1f) << 4;
-		exp = rate_atmf >> 5;
-
-		/* 
-			instead of '/ 512', use '>> 9' to prevent a call
-			to divdu3 on x86 platforms
-		*/
-		rate_cps = (unsigned long long) (1UL << exp) * (man + 512) >> 9;
-
-		if (rate_cps < 10)
-			rate_cps = 10;	/* 2.2.1 minimum payload rate is 10 cps */
-
-		for (i = 255; i > 0; i--)
-			if ((*rategrid)[i/16][i%16] >= rate_cps)
-				break;	 /* pick nearest rate instead? */
-
-		/*
-		 * each table entry is 16 bits: (rate grid index (8 bits)
-		 * and a buffer limit (8 bits)
-		 * there are two table entries in each 32-bit register
-		 */
-
-#ifdef notdef
-		buf = rate_cps * he_dev->tx_numbuffs /
-				(he_dev->atm_dev->link_rate * 2);
-#else
-		/* this is pretty, but avoids _divdu3 and is mostly correct */
-		mult = he_dev->atm_dev->link_rate / ATM_OC3_PCR;
-		if (rate_cps > (272ULL * mult))
-			buf = 4;
-		else if (rate_cps > (204ULL * mult))
-			buf = 3;
-		else if (rate_cps > (136ULL * mult))
-			buf = 2;
-		else if (rate_cps > (68ULL * mult))
-			buf = 1;
-		else
-			buf = 0;
-#endif
-		if (buf > buf_limit)
-			buf = buf_limit;
-		reg = (reg << 16) | ((i << 8) | buf);
-
-#define RTGTBL_OFFSET 0x400
-	  
-		if (rate_atmf & 0x1)
-			he_writel_rcm(he_dev, reg,
-				CONFIG_RCMABR + RTGTBL_OFFSET + (rate_atmf >> 1));
-
-		++rate_atmf;
-	}
-
-	kfree(rategrid);
-	return 0;
-}
-
-static int he_init_group(struct he_dev *he_dev, int group)
-{
-	struct he_buff *heb, *next;
-	dma_addr_t mapping;
-	int i;
-
-	he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
-	he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
-	he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
-	he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-		  G0_RBPS_BS + (group * 32));
-
-	/* bitmap table */
-	he_dev->rbpl_table = bitmap_zalloc(RBPL_TABLE_SIZE, GFP_KERNEL);
-	if (!he_dev->rbpl_table) {
-		hprintk("unable to allocate rbpl bitmap table\n");
-		return -ENOMEM;
-	}
-
-	/* rbpl_virt 64-bit pointers */
-	he_dev->rbpl_virt = kmalloc_objs(*he_dev->rbpl_virt, RBPL_TABLE_SIZE);
-	if (!he_dev->rbpl_virt) {
-		hprintk("unable to allocate rbpl virt table\n");
-		goto out_free_rbpl_table;
-	}
-
-	/* large buffer pool */
-	he_dev->rbpl_pool = dma_pool_create("rbpl", &he_dev->pci_dev->dev,
-					    CONFIG_RBPL_BUFSIZE, 64, 0);
-	if (he_dev->rbpl_pool == NULL) {
-		hprintk("unable to create rbpl pool\n");
-		goto out_free_rbpl_virt;
-	}
-
-	he_dev->rbpl_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_RBPL_SIZE * sizeof(struct he_rbp),
-					       &he_dev->rbpl_phys, GFP_KERNEL);
-	if (he_dev->rbpl_base == NULL) {
-		hprintk("failed to alloc rbpl_base\n");
-		goto out_destroy_rbpl_pool;
-	}
-
-	INIT_LIST_HEAD(&he_dev->rbpl_outstanding);
-
-	for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
-
-		heb = dma_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL, &mapping);
-		if (!heb)
-			goto out_free_rbpl;
-		heb->mapping = mapping;
-		list_add(&heb->entry, &he_dev->rbpl_outstanding);
-
-		set_bit(i, he_dev->rbpl_table);
-		he_dev->rbpl_virt[i] = heb;
-		he_dev->rbpl_hint = i + 1;
-		he_dev->rbpl_base[i].idx =  i << RBP_IDX_OFFSET;
-		he_dev->rbpl_base[i].phys = mapping + offsetof(struct he_buff, data);
-	}
-	he_dev->rbpl_tail = &he_dev->rbpl_base[CONFIG_RBPL_SIZE - 1];
-
-	he_writel(he_dev, he_dev->rbpl_phys, G0_RBPL_S + (group * 32));
-	he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail),
-						G0_RBPL_T + (group * 32));
-	he_writel(he_dev, (CONFIG_RBPL_BUFSIZE - sizeof(struct he_buff))/4,
-						G0_RBPL_BS + (group * 32));
-	he_writel(he_dev,
-			RBP_THRESH(CONFIG_RBPL_THRESH) |
-			RBP_QSIZE(CONFIG_RBPL_SIZE - 1) |
-			RBP_INT_ENB,
-						G0_RBPL_QI + (group * 32));
-
-	/* rx buffer ready queue */
-
-	he_dev->rbrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
-					       &he_dev->rbrq_phys, GFP_KERNEL);
-	if (he_dev->rbrq_base == NULL) {
-		hprintk("failed to allocate rbrq\n");
-		goto out_free_rbpl;
-	}
-
-	he_dev->rbrq_head = he_dev->rbrq_base;
-	he_writel(he_dev, he_dev->rbrq_phys, G0_RBRQ_ST + (group * 16));
-	he_writel(he_dev, 0, G0_RBRQ_H + (group * 16));
-	he_writel(he_dev,
-		RBRQ_THRESH(CONFIG_RBRQ_THRESH) | RBRQ_SIZE(CONFIG_RBRQ_SIZE - 1),
-						G0_RBRQ_Q + (group * 16));
-	if (irq_coalesce) {
-		hprintk("coalescing interrupts\n");
-		he_writel(he_dev, RBRQ_TIME(768) | RBRQ_COUNT(7),
-						G0_RBRQ_I + (group * 16));
-	} else
-		he_writel(he_dev, RBRQ_TIME(0) | RBRQ_COUNT(1),
-						G0_RBRQ_I + (group * 16));
-
-	/* tx buffer ready queue */
-
-	he_dev->tbrq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					       CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
-					       &he_dev->tbrq_phys, GFP_KERNEL);
-	if (he_dev->tbrq_base == NULL) {
-		hprintk("failed to allocate tbrq\n");
-		goto out_free_rbpq_base;
-	}
-
-	he_dev->tbrq_head = he_dev->tbrq_base;
-
-	he_writel(he_dev, he_dev->tbrq_phys, G0_TBRQ_B_T + (group * 16));
-	he_writel(he_dev, 0, G0_TBRQ_H + (group * 16));
-	he_writel(he_dev, CONFIG_TBRQ_SIZE - 1, G0_TBRQ_S + (group * 16));
-	he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16));
-
-	return 0;
-
-out_free_rbpq_base:
-	dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBRQ_SIZE *
-			  sizeof(struct he_rbrq), he_dev->rbrq_base,
-			  he_dev->rbrq_phys);
-out_free_rbpl:
-	list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
-		dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-
-	dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBPL_SIZE *
-			  sizeof(struct he_rbp), he_dev->rbpl_base,
-			  he_dev->rbpl_phys);
-out_destroy_rbpl_pool:
-	dma_pool_destroy(he_dev->rbpl_pool);
-out_free_rbpl_virt:
-	kfree(he_dev->rbpl_virt);
-out_free_rbpl_table:
-	bitmap_free(he_dev->rbpl_table);
-
-	return -ENOMEM;
-}
-
-static int he_init_irq(struct he_dev *he_dev)
-{
-	int i;
-
-	/* 2.9.3.5  tail offset for each interrupt queue is located after the
-		    end of the interrupt queue */
-
-	he_dev->irq_base = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					      (CONFIG_IRQ_SIZE + 1) * sizeof(struct he_irq),
-					      &he_dev->irq_phys, GFP_KERNEL);
-	if (he_dev->irq_base == NULL) {
-		hprintk("failed to allocate irq\n");
-		return -ENOMEM;
-	}
-	he_dev->irq_tailoffset = (unsigned *)
-					&he_dev->irq_base[CONFIG_IRQ_SIZE];
-	*he_dev->irq_tailoffset = 0;
-	he_dev->irq_head = he_dev->irq_base;
-	he_dev->irq_tail = he_dev->irq_base;
-
-	for (i = 0; i < CONFIG_IRQ_SIZE; ++i)
-		he_dev->irq_base[i].isw = ITYPE_INVALID;
-
-	he_writel(he_dev, he_dev->irq_phys, IRQ0_BASE);
-	he_writel(he_dev,
-		IRQ_SIZE(CONFIG_IRQ_SIZE) | IRQ_THRESH(CONFIG_IRQ_THRESH),
-								IRQ0_HEAD);
-	he_writel(he_dev, IRQ_INT_A | IRQ_TYPE_LINE, IRQ0_CNTL);
-	he_writel(he_dev, 0x0, IRQ0_DATA);
-
-	he_writel(he_dev, 0x0, IRQ1_BASE);
-	he_writel(he_dev, 0x0, IRQ1_HEAD);
-	he_writel(he_dev, 0x0, IRQ1_CNTL);
-	he_writel(he_dev, 0x0, IRQ1_DATA);
-
-	he_writel(he_dev, 0x0, IRQ2_BASE);
-	he_writel(he_dev, 0x0, IRQ2_HEAD);
-	he_writel(he_dev, 0x0, IRQ2_CNTL);
-	he_writel(he_dev, 0x0, IRQ2_DATA);
-
-	he_writel(he_dev, 0x0, IRQ3_BASE);
-	he_writel(he_dev, 0x0, IRQ3_HEAD);
-	he_writel(he_dev, 0x0, IRQ3_CNTL);
-	he_writel(he_dev, 0x0, IRQ3_DATA);
-
-	/* 2.9.3.2 interrupt queue mapping registers */
-
-	he_writel(he_dev, 0x0, GRP_10_MAP);
-	he_writel(he_dev, 0x0, GRP_32_MAP);
-	he_writel(he_dev, 0x0, GRP_54_MAP);
-	he_writel(he_dev, 0x0, GRP_76_MAP);
-
-	if (request_irq(he_dev->pci_dev->irq,
-			he_irq_handler, IRQF_SHARED, DEV_LABEL, he_dev)) {
-		hprintk("irq %d already in use\n", he_dev->pci_dev->irq);
-		return -EINVAL;
-	}   
-
-	he_dev->irq = he_dev->pci_dev->irq;
-
-	return 0;
-}
-
-static int he_start(struct atm_dev *dev)
-{
-	struct he_dev *he_dev;
-	struct pci_dev *pci_dev;
-	unsigned long membase;
-
-	u16 command;
-	u32 gen_cntl_0, host_cntl, lb_swap;
-	u8 cache_size, timer;
-	
-	unsigned err;
-	unsigned int status, reg;
-	int i, group;
-
-	he_dev = HE_DEV(dev);
-	pci_dev = he_dev->pci_dev;
-
-	membase = pci_resource_start(pci_dev, 0);
-	HPRINTK("membase = 0x%lx  irq = %d.\n", membase, pci_dev->irq);
-
-	/*
-	 * pci bus controller initialization 
-	 */
-
-	/* 4.3 pci bus controller-specific initialization */
-	if (pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0) != 0) {
-		hprintk("can't read GEN_CNTL_0\n");
-		return -EINVAL;
-	}
-	gen_cntl_0 |= (MRL_ENB | MRM_ENB | IGNORE_TIMEOUT);
-	if (pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0) != 0) {
-		hprintk("can't write GEN_CNTL_0.\n");
-		return -EINVAL;
-	}
-
-	if (pci_read_config_word(pci_dev, PCI_COMMAND, &command) != 0) {
-		hprintk("can't read PCI_COMMAND.\n");
-		return -EINVAL;
-	}
-
-	command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE);
-	if (pci_write_config_word(pci_dev, PCI_COMMAND, command) != 0) {
-		hprintk("can't enable memory.\n");
-		return -EINVAL;
-	}
-
-	if (pci_read_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, &cache_size)) {
-		hprintk("can't read cache line size?\n");
-		return -EINVAL;
-	}
-
-	if (cache_size < 16) {
-		cache_size = 16;
-		if (pci_write_config_byte(pci_dev, PCI_CACHE_LINE_SIZE, cache_size))
-			hprintk("can't set cache line size to %d\n", cache_size);
-	}
-
-	if (pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &timer)) {
-		hprintk("can't read latency timer?\n");
-		return -EINVAL;
-	}
-
-	/* from table 3.9
-	 *
-	 * LAT_TIMER = 1 + AVG_LAT + BURST_SIZE/BUS_SIZE
-	 * 
-	 * AVG_LAT: The average first data read/write latency [maximum 16 clock cycles]
-	 * BURST_SIZE: 1536 bytes (read) for 622, 768 bytes (read) for 155 [192 clock cycles]
-	 *
-	 */ 
-#define LAT_TIMER 209
-	if (timer < LAT_TIMER) {
-		HPRINTK("latency timer was %d, setting to %d\n", timer, LAT_TIMER);
-		timer = LAT_TIMER;
-		if (pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, timer))
-			hprintk("can't set latency timer to %d\n", timer);
-	}
-
-	if (!(he_dev->membase = ioremap(membase, HE_REGMAP_SIZE))) {
-		hprintk("can't set up page mapping\n");
-		return -EINVAL;
-	}
-
-	/* 4.4 card reset */
-	he_writel(he_dev, 0x0, RESET_CNTL);
-	he_writel(he_dev, 0xff, RESET_CNTL);
-
-	msleep(16);	/* 16 ms */
-	status = he_readl(he_dev, RESET_CNTL);
-	if ((status & BOARD_RST_STATUS) == 0) {
-		hprintk("reset failed\n");
-		return -EINVAL;
-	}
-
-	/* 4.5 set bus width */
-	host_cntl = he_readl(he_dev, HOST_CNTL);
-	if (host_cntl & PCI_BUS_SIZE64)
-		gen_cntl_0 |= ENBL_64;
-	else
-		gen_cntl_0 &= ~ENBL_64;
-
-	if (disable64 == 1) {
-		hprintk("disabling 64-bit pci bus transfers\n");
-		gen_cntl_0 &= ~ENBL_64;
-	}
-
-	if (gen_cntl_0 & ENBL_64)
-		hprintk("64-bit transfers enabled\n");
-
-	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-	/* 4.7 read prom contents */
-	for (i = 0; i < PROD_ID_LEN; ++i)
-		he_dev->prod_id[i] = read_prom_byte(he_dev, PROD_ID + i);
-
-	he_dev->media = read_prom_byte(he_dev, MEDIA);
-
-	for (i = 0; i < 6; ++i)
-		dev->esi[i] = read_prom_byte(he_dev, MAC_ADDR + i);
-
-	hprintk("%s%s, %pM\n", he_dev->prod_id,
-		he_dev->media & 0x40 ? "SM" : "MM", dev->esi);
-	he_dev->atm_dev->link_rate = he_is622(he_dev) ?
-						ATM_OC12_PCR : ATM_OC3_PCR;
-
-	/* 4.6 set host endianess */
-	lb_swap = he_readl(he_dev, LB_SWAP);
-	if (he_is622(he_dev))
-		lb_swap &= ~XFER_SIZE;		/* 4 cells */
-	else
-		lb_swap |= XFER_SIZE;		/* 8 cells */
-#ifdef __BIG_ENDIAN
-	lb_swap |= DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST;
-#else
-	lb_swap &= ~(DESC_WR_SWAP | INTR_SWAP | BIG_ENDIAN_HOST |
-			DATA_WR_SWAP | DATA_RD_SWAP | DESC_RD_SWAP);
-#endif /* __BIG_ENDIAN */
-	he_writel(he_dev, lb_swap, LB_SWAP);
-
-	/* 4.8 sdram controller initialization */
-	he_writel(he_dev, he_is622(he_dev) ? LB_64_ENB : 0x0, SDRAM_CTL);
-
-	/* 4.9 initialize rnum value */
-	lb_swap |= SWAP_RNUM_MAX(0xf);
-	he_writel(he_dev, lb_swap, LB_SWAP);
-
-	/* 4.10 initialize the interrupt queues */
-	if ((err = he_init_irq(he_dev)) != 0)
-		return err;
-
-	/* 4.11 enable pci bus controller state machines */
-	host_cntl |= (OUTFF_ENB | CMDFF_ENB |
-				QUICK_RD_RETRY | QUICK_WR_RETRY | PERR_INT_ENB);
-	he_writel(he_dev, host_cntl, HOST_CNTL);
-
-	gen_cntl_0 |= INT_PROC_ENBL|INIT_ENB;
-	pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-	/*
-	 * atm network controller initialization
-	 */
-
-	/* 5.1.1 generic configuration state */
-
-	/*
-	 *		local (cell) buffer memory map
-	 *                    
-	 *             HE155                          HE622
-	 *                                                      
-	 *        0 ____________1023 bytes  0 _______________________2047 bytes
-	 *         |            |            |                   |   |
-	 *         |  utility   |            |        rx0        |   |
-	 *        5|____________|         255|___________________| u |
-	 *        6|            |         256|                   | t |
-	 *         |            |            |                   | i |
-	 *         |    rx0     |     row    |        tx         | l |
-	 *         |            |            |                   | i |
-	 *         |            |         767|___________________| t |
-	 *      517|____________|         768|                   | y |
-	 * row  518|            |            |        rx1        |   |
-	 *         |            |        1023|___________________|___|
-	 *         |            |
-	 *         |    tx      |
-	 *         |            |
-	 *         |            |
-	 *     1535|____________|
-	 *     1536|            |
-	 *         |    rx1     |
-	 *     2047|____________|
-	 *
-	 */
-
-	/* total 4096 connections */
-	he_dev->vcibits = CONFIG_DEFAULT_VCIBITS;
-	he_dev->vpibits = CONFIG_DEFAULT_VPIBITS;
-
-	if (nvpibits != -1 && nvcibits != -1 && nvpibits+nvcibits != HE_MAXCIDBITS) {
-		hprintk("nvpibits + nvcibits != %d\n", HE_MAXCIDBITS);
-		return -ENODEV;
-	}
-
-	if (nvpibits != -1) {
-		he_dev->vpibits = nvpibits;
-		he_dev->vcibits = HE_MAXCIDBITS - nvpibits;
-	}
-
-	if (nvcibits != -1) {
-		he_dev->vcibits = nvcibits;
-		he_dev->vpibits = HE_MAXCIDBITS - nvcibits;
-	}
-
-
-	if (he_is622(he_dev)) {
-		he_dev->cells_per_row = 40;
-		he_dev->bytes_per_row = 2048;
-		he_dev->r0_numrows = 256;
-		he_dev->tx_numrows = 512;
-		he_dev->r1_numrows = 256;
-		he_dev->r0_startrow = 0;
-		he_dev->tx_startrow = 256;
-		he_dev->r1_startrow = 768;
-	} else {
-		he_dev->cells_per_row = 20;
-		he_dev->bytes_per_row = 1024;
-		he_dev->r0_numrows = 512;
-		he_dev->tx_numrows = 1018;
-		he_dev->r1_numrows = 512;
-		he_dev->r0_startrow = 6;
-		he_dev->tx_startrow = 518;
-		he_dev->r1_startrow = 1536;
-	}
-
-	he_dev->cells_per_lbuf = 4;
-	he_dev->buffer_limit = 4;
-	he_dev->r0_numbuffs = he_dev->r0_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r0_numbuffs > 2560)
-		he_dev->r0_numbuffs = 2560;
-
-	he_dev->r1_numbuffs = he_dev->r1_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->r1_numbuffs > 2560)
-		he_dev->r1_numbuffs = 2560;
-
-	he_dev->tx_numbuffs = he_dev->tx_numrows *
-				he_dev->cells_per_row / he_dev->cells_per_lbuf;
-	if (he_dev->tx_numbuffs > 5120)
-		he_dev->tx_numbuffs = 5120;
-
-	/* 5.1.2 configure hardware dependent registers */
-
-	he_writel(he_dev, 
-		SLICE_X(0x2) | ARB_RNUM_MAX(0xf) | TH_PRTY(0x3) |
-		RH_PRTY(0x3) | TL_PRTY(0x2) | RL_PRTY(0x1) |
-		(he_is622(he_dev) ? BUS_MULTI(0x28) : BUS_MULTI(0x46)) |
-		(he_is622(he_dev) ? NET_PREF(0x50) : NET_PREF(0x8c)),
-								LBARB);
-
-	he_writel(he_dev, BANK_ON |
-		(he_is622(he_dev) ? (REF_RATE(0x384) | WIDE_DATA) : REF_RATE(0x150)),
-								SDRAMCON);
-
-	he_writel(he_dev,
-		(he_is622(he_dev) ? RM_BANK_WAIT(1) : RM_BANK_WAIT(0)) |
-						RM_RW_WAIT(1), RCMCONFIG);
-	he_writel(he_dev,
-		(he_is622(he_dev) ? TM_BANK_WAIT(2) : TM_BANK_WAIT(1)) |
-						TM_RW_WAIT(1), TCMCONFIG);
-
-	he_writel(he_dev, he_dev->cells_per_lbuf * ATM_CELL_PAYLOAD, LB_CONFIG);
-
-	he_writel(he_dev, 
-		(he_is622(he_dev) ? UT_RD_DELAY(8) : UT_RD_DELAY(0)) |
-		(he_is622(he_dev) ? RC_UT_MODE(0) : RC_UT_MODE(1)) |
-		RX_VALVP(he_dev->vpibits) |
-		RX_VALVC(he_dev->vcibits),			 RC_CONFIG);
-
-	he_writel(he_dev, DRF_THRESH(0x20) |
-		(he_is622(he_dev) ? TX_UT_MODE(0) : TX_UT_MODE(1)) |
-		TX_VCI_MASK(he_dev->vcibits) |
-		LBFREE_CNT(he_dev->tx_numbuffs), 		TX_CONFIG);
-
-	he_writel(he_dev, 0x0, TXAAL5_PROTO);
-
-	he_writel(he_dev, PHY_INT_ENB |
-		(he_is622(he_dev) ? PTMR_PRE(67 - 1) : PTMR_PRE(50 - 1)),
-								RH_CONFIG);
-
-	/* 5.1.3 initialize connection memory */
-
-	for (i = 0; i < TCM_MEM_SIZE; ++i)
-		he_writel_tcm(he_dev, 0, i);
-
-	for (i = 0; i < RCM_MEM_SIZE; ++i)
-		he_writel_rcm(he_dev, 0, i);
-
-	/*
-	 *	transmit connection memory map
-	 *
-	 *                  tx memory
-	 *          0x0 ___________________
-	 *             |                   |
-	 *             |                   |
-	 *             |       TSRa        |
-	 *             |                   |
-	 *             |                   |
-	 *       0x8000|___________________|
-	 *             |                   |
-	 *             |       TSRb        |
-	 *       0xc000|___________________|
-	 *             |                   |
-	 *             |       TSRc        |
-	 *       0xe000|___________________|
-	 *             |       TSRd        |
-	 *       0xf000|___________________|
-	 *             |       tmABR       |
-	 *      0x10000|___________________|
-	 *             |                   |
-	 *             |       tmTPD       |
-	 *             |___________________|
-	 *             |                   |
-	 *                      ....
-	 *      0x1ffff|___________________|
-	 *
-	 *
-	 */
-
-	he_writel(he_dev, CONFIG_TSRB, TSRB_BA);
-	he_writel(he_dev, CONFIG_TSRC, TSRC_BA);
-	he_writel(he_dev, CONFIG_TSRD, TSRD_BA);
-	he_writel(he_dev, CONFIG_TMABR, TMABR_BA);
-	he_writel(he_dev, CONFIG_TPDBA, TPD_BA);
-
-
-	/*
-	 *	receive connection memory map
-	 *
-	 *          0x0 ___________________
-	 *             |                   |
-	 *             |                   |
-	 *             |       RSRa        |
-	 *             |                   |
-	 *             |                   |
-	 *       0x8000|___________________|
-	 *             |                   |
-	 *             |             rx0/1 |
-	 *             |       LBM         |   link lists of local
-	 *             |             tx    |   buffer memory 
-	 *             |                   |
-	 *       0xd000|___________________|
-	 *             |                   |
-	 *             |      rmABR        |
-	 *       0xe000|___________________|
-	 *             |                   |
-	 *             |       RSRb        |
-	 *             |___________________|
-	 *             |                   |
-	 *                      ....
-	 *       0xffff|___________________|
-	 */
-
-	he_writel(he_dev, 0x08000, RCMLBM_BA);
-	he_writel(he_dev, 0x0e000, RCMRSRB_BA);
-	he_writel(he_dev, 0x0d800, RCMABR_BA);
-
-	/* 5.1.4 initialize local buffer free pools linked lists */
-
-	he_init_rx_lbfp0(he_dev);
-	he_init_rx_lbfp1(he_dev);
-
-	he_writel(he_dev, 0x0, RLBC_H);
-	he_writel(he_dev, 0x0, RLBC_T);
-	he_writel(he_dev, 0x0, RLBC_H2);
-
-	he_writel(he_dev, 512, RXTHRSH);	/* 10% of r0+r1 buffers */
-	he_writel(he_dev, 256, LITHRSH); 	/* 5% of r0+r1 buffers */
-
-	he_init_tx_lbfp(he_dev);
-
-	he_writel(he_dev, he_is622(he_dev) ? 0x104780 : 0x800, UBUFF_BA);
-
-	/* 5.1.5 initialize intermediate receive queues */
-
-	if (he_is622(he_dev)) {
-		he_writel(he_dev, 0x000f, G0_INMQ_S);
-		he_writel(he_dev, 0x200f, G0_INMQ_L);
-
-		he_writel(he_dev, 0x001f, G1_INMQ_S);
-		he_writel(he_dev, 0x201f, G1_INMQ_L);
-
-		he_writel(he_dev, 0x002f, G2_INMQ_S);
-		he_writel(he_dev, 0x202f, G2_INMQ_L);
-
-		he_writel(he_dev, 0x003f, G3_INMQ_S);
-		he_writel(he_dev, 0x203f, G3_INMQ_L);
-
-		he_writel(he_dev, 0x004f, G4_INMQ_S);
-		he_writel(he_dev, 0x204f, G4_INMQ_L);
-
-		he_writel(he_dev, 0x005f, G5_INMQ_S);
-		he_writel(he_dev, 0x205f, G5_INMQ_L);
-
-		he_writel(he_dev, 0x006f, G6_INMQ_S);
-		he_writel(he_dev, 0x206f, G6_INMQ_L);
-
-		he_writel(he_dev, 0x007f, G7_INMQ_S);
-		he_writel(he_dev, 0x207f, G7_INMQ_L);
-	} else {
-		he_writel(he_dev, 0x0000, G0_INMQ_S);
-		he_writel(he_dev, 0x0008, G0_INMQ_L);
-
-		he_writel(he_dev, 0x0001, G1_INMQ_S);
-		he_writel(he_dev, 0x0009, G1_INMQ_L);
-
-		he_writel(he_dev, 0x0002, G2_INMQ_S);
-		he_writel(he_dev, 0x000a, G2_INMQ_L);
-
-		he_writel(he_dev, 0x0003, G3_INMQ_S);
-		he_writel(he_dev, 0x000b, G3_INMQ_L);
-
-		he_writel(he_dev, 0x0004, G4_INMQ_S);
-		he_writel(he_dev, 0x000c, G4_INMQ_L);
-
-		he_writel(he_dev, 0x0005, G5_INMQ_S);
-		he_writel(he_dev, 0x000d, G5_INMQ_L);
-
-		he_writel(he_dev, 0x0006, G6_INMQ_S);
-		he_writel(he_dev, 0x000e, G6_INMQ_L);
-
-		he_writel(he_dev, 0x0007, G7_INMQ_S);
-		he_writel(he_dev, 0x000f, G7_INMQ_L);
-	}
-
-	/* 5.1.6 application tunable parameters */
-
-	he_writel(he_dev, 0x0, MCC);
-	he_writel(he_dev, 0x0, OEC);
-	he_writel(he_dev, 0x0, DCC);
-	he_writel(he_dev, 0x0, CEC);
-	
-	/* 5.1.7 cs block initialization */
-
-	he_init_cs_block(he_dev);
-
-	/* 5.1.8 cs block connection memory initialization */
-	
-	if (he_init_cs_block_rcm(he_dev) < 0)
-		return -ENOMEM;
-
-	/* 5.1.10 initialize host structures */
-
-	he_init_tpdrq(he_dev);
-
-	he_dev->tpd_pool = dma_pool_create("tpd", &he_dev->pci_dev->dev,
-					   sizeof(struct he_tpd), TPD_ALIGNMENT, 0);
-	if (he_dev->tpd_pool == NULL) {
-		hprintk("unable to create tpd dma_pool\n");
-		return -ENOMEM;         
-	}
-
-	INIT_LIST_HEAD(&he_dev->outstanding_tpds);
-
-	if (he_init_group(he_dev, 0) != 0)
-		return -ENOMEM;
-
-	for (group = 1; group < HE_NUM_GROUPS; ++group) {
-		he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32));
-		he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-						G0_RBPS_BS + (group * 32));
-
-		he_writel(he_dev, 0x0, G0_RBPL_S + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPL_T + (group * 32));
-		he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0),
-						G0_RBPL_QI + (group * 32));
-		he_writel(he_dev, 0x0, G0_RBPL_BS + (group * 32));
-
-		he_writel(he_dev, 0x0, G0_RBRQ_ST + (group * 16));
-		he_writel(he_dev, 0x0, G0_RBRQ_H + (group * 16));
-		he_writel(he_dev, RBRQ_THRESH(0x1) | RBRQ_SIZE(0x0),
-						G0_RBRQ_Q + (group * 16));
-		he_writel(he_dev, 0x0, G0_RBRQ_I + (group * 16));
-
-		he_writel(he_dev, 0x0, G0_TBRQ_B_T + (group * 16));
-		he_writel(he_dev, 0x0, G0_TBRQ_H + (group * 16));
-		he_writel(he_dev, TBRQ_THRESH(0x1),
-						G0_TBRQ_THRESH + (group * 16));
-		he_writel(he_dev, 0x0, G0_TBRQ_S + (group * 16));
-	}
-
-	/* host status page */
-
-	he_dev->hsp = dma_alloc_coherent(&he_dev->pci_dev->dev,
-					 sizeof(struct he_hsp),
-					 &he_dev->hsp_phys, GFP_KERNEL);
-	if (he_dev->hsp == NULL) {
-		hprintk("failed to allocate host status page\n");
-		return -ENOMEM;
-	}
-	he_writel(he_dev, he_dev->hsp_phys, HSP_BA);
-
-	/* initialize framer */
-
-#ifdef CONFIG_ATM_HE_USE_SUNI
-	if (he_isMM(he_dev))
-		suni_init(he_dev->atm_dev);
-	if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->start)
-		he_dev->atm_dev->phy->start(he_dev->atm_dev);
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-
-	if (sdh) {
-		/* this really should be in suni.c but for now... */
-		int val;
-
-		val = he_phy_get(he_dev->atm_dev, SUNI_TPOP_APM);
-		val = (val & ~SUNI_TPOP_APM_S) | (SUNI_TPOP_S_SDH << SUNI_TPOP_APM_S_SHIFT);
-		he_phy_put(he_dev->atm_dev, val, SUNI_TPOP_APM);
-		he_phy_put(he_dev->atm_dev, SUNI_TACP_IUCHP_CLP, SUNI_TACP_IUCHP);
-	}
-
-	/* 5.1.12 enable transmit and receive */
-
-	reg = he_readl_mbox(he_dev, CS_ERCTL0);
-	reg |= TX_ENABLE|ER_ENABLE;
-	he_writel_mbox(he_dev, reg, CS_ERCTL0);
-
-	reg = he_readl(he_dev, RC_CONFIG);
-	reg |= RX_ENABLE;
-	he_writel(he_dev, reg, RC_CONFIG);
-
-	for (i = 0; i < HE_NUM_CS_STPER; ++i) {
-		he_dev->cs_stper[i].inuse = 0;
-		he_dev->cs_stper[i].pcr = -1;
-	}
-	he_dev->total_bw = 0;
-
-
-	/* atm linux initialization */
-
-	he_dev->atm_dev->ci_range.vpi_bits = he_dev->vpibits;
-	he_dev->atm_dev->ci_range.vci_bits = he_dev->vcibits;
-
-	he_dev->irq_peak = 0;
-	he_dev->rbrq_peak = 0;
-	he_dev->rbpl_peak = 0;
-	he_dev->tbrq_peak = 0;
-
-	HPRINTK("hell bent for leather!\n");
-
-	return 0;
-}
-
-static void
-he_stop(struct he_dev *he_dev)
-{
-	struct he_buff *heb, *next;
-	struct pci_dev *pci_dev;
-	u32 gen_cntl_0, reg;
-	u16 command;
-
-	pci_dev = he_dev->pci_dev;
-
-	/* disable interrupts */
-
-	if (he_dev->membase) {
-		pci_read_config_dword(pci_dev, GEN_CNTL_0, &gen_cntl_0);
-		gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB);
-		pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0);
-
-		tasklet_disable(&he_dev->tasklet);
-
-		/* disable recv and transmit */
-
-		reg = he_readl_mbox(he_dev, CS_ERCTL0);
-		reg &= ~(TX_ENABLE|ER_ENABLE);
-		he_writel_mbox(he_dev, reg, CS_ERCTL0);
-
-		reg = he_readl(he_dev, RC_CONFIG);
-		reg &= ~(RX_ENABLE);
-		he_writel(he_dev, reg, RC_CONFIG);
-	}
-
-#ifdef CONFIG_ATM_HE_USE_SUNI
-	if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->stop)
-		he_dev->atm_dev->phy->stop(he_dev->atm_dev);
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-
-	if (he_dev->irq)
-		free_irq(he_dev->irq, he_dev);
-
-	if (he_dev->irq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, (CONFIG_IRQ_SIZE + 1)
-				  * sizeof(struct he_irq), he_dev->irq_base, he_dev->irq_phys);
-
-	if (he_dev->hsp)
-		dma_free_coherent(&he_dev->pci_dev->dev, sizeof(struct he_hsp),
-				  he_dev->hsp, he_dev->hsp_phys);
-
-	if (he_dev->rbpl_base) {
-		list_for_each_entry_safe(heb, next, &he_dev->rbpl_outstanding, entry)
-			dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBPL_SIZE
-				  * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys);
-	}
-
-	kfree(he_dev->rbpl_virt);
-	bitmap_free(he_dev->rbpl_table);
-	dma_pool_destroy(he_dev->rbpl_pool);
-
-	if (he_dev->rbrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq),
-				  he_dev->rbrq_base, he_dev->rbrq_phys);
-
-	if (he_dev->tbrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq),
-				  he_dev->tbrq_base, he_dev->tbrq_phys);
-
-	if (he_dev->tpdrq_base)
-		dma_free_coherent(&he_dev->pci_dev->dev,
-				  CONFIG_TPDRQ_SIZE * sizeof(struct he_tpdrq),
-				  he_dev->tpdrq_base, he_dev->tpdrq_phys);
-
-	dma_pool_destroy(he_dev->tpd_pool);
-
-	if (he_dev->pci_dev) {
-		pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command);
-		command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-		pci_write_config_word(he_dev->pci_dev, PCI_COMMAND, command);
-	}
-	
-	if (he_dev->membase)
-		iounmap(he_dev->membase);
-}
-
-static struct he_tpd *
-__alloc_tpd(struct he_dev *he_dev)
-{
-	struct he_tpd *tpd;
-	dma_addr_t mapping;
-
-	tpd = dma_pool_alloc(he_dev->tpd_pool, GFP_ATOMIC, &mapping);
-	if (tpd == NULL)
-		return NULL;
-			
-	tpd->status = TPD_ADDR(mapping);
-	tpd->reserved = 0; 
-	tpd->iovec[0].addr = 0; tpd->iovec[0].len = 0;
-	tpd->iovec[1].addr = 0; tpd->iovec[1].len = 0;
-	tpd->iovec[2].addr = 0; tpd->iovec[2].len = 0;
-
-	return tpd;
-}
-
-#define AAL5_LEN(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-6] << 8) |	\
-				(((unsigned char *)(buf))[(len)-5]))
-
-/* 2.10.1.2 receive
- *
- * aal5 packets can optionally return the tcp checksum in the lower
- * 16 bits of the crc (RSR0_TCP_CKSUM)
- */
-
-#define TCP_CKSUM(buf,len) 						\
-			((((unsigned char *)(buf))[(len)-2] << 8) |	\
-				(((unsigned char *)(buf))[(len-1)]))
-
-static int
-he_service_rbrq(struct he_dev *he_dev, int group)
-{
-	struct he_rbrq *rbrq_tail = (struct he_rbrq *)
-				((unsigned long)he_dev->rbrq_base |
-					he_dev->hsp->group[group].rbrq_tail);
-	unsigned cid, lastcid = -1;
-	struct sk_buff *skb;
-	struct atm_vcc *vcc = NULL;
-	struct he_vcc *he_vcc;
-	struct he_buff *heb, *next;
-	int i;
-	int pdus_assembled = 0;
-	int updated = 0;
-
-	read_lock(&vcc_sklist_lock);
-	while (he_dev->rbrq_head != rbrq_tail) {
-		++updated;
-
-		HPRINTK("%p rbrq%d 0x%x len=%d cid=0x%x %s%s%s%s%s%s\n",
-			he_dev->rbrq_head, group,
-			RBRQ_ADDR(he_dev->rbrq_head),
-			RBRQ_BUFLEN(he_dev->rbrq_head),
-			RBRQ_CID(he_dev->rbrq_head),
-			RBRQ_CRC_ERR(he_dev->rbrq_head) ? " CRC_ERR" : "",
-			RBRQ_LEN_ERR(he_dev->rbrq_head) ? " LEN_ERR" : "",
-			RBRQ_END_PDU(he_dev->rbrq_head) ? " END_PDU" : "",
-			RBRQ_AAL5_PROT(he_dev->rbrq_head) ? " AAL5_PROT" : "",
-			RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "",
-			RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : "");
-
-		i = RBRQ_ADDR(he_dev->rbrq_head) >> RBP_IDX_OFFSET;
-		heb = he_dev->rbpl_virt[i];
-
-		cid = RBRQ_CID(he_dev->rbrq_head);
-		if (cid != lastcid)
-			vcc = __find_vcc(he_dev, cid);
-		lastcid = cid;
-
-		if (vcc == NULL || (he_vcc = HE_VCC(vcc)) == NULL) {
-			hprintk("vcc/he_vcc == NULL  (cid 0x%x)\n", cid);
-			if (!RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
-				clear_bit(i, he_dev->rbpl_table);
-				list_del(&heb->entry);
-				dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-			}
-					
-			goto next_rbrq_entry;
-		}
-
-		if (RBRQ_HBUF_ERR(he_dev->rbrq_head)) {
-			hprintk("HBUF_ERR!  (cid 0x%x)\n", cid);
-			atomic_inc(&vcc->stats->rx_drop);
-			goto return_host_buffers;
-		}
-
-		heb->len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4;
-		clear_bit(i, he_dev->rbpl_table);
-		list_move_tail(&heb->entry, &he_vcc->buffers);
-		he_vcc->pdu_len += heb->len;
-
-		if (RBRQ_CON_CLOSED(he_dev->rbrq_head)) {
-			lastcid = -1;
-			HPRINTK("wake_up rx_waitq  (cid 0x%x)\n", cid);
-			wake_up(&he_vcc->rx_waitq);
-			goto return_host_buffers;
-		}
-
-		if (!RBRQ_END_PDU(he_dev->rbrq_head))
-			goto next_rbrq_entry;
-
-		if (RBRQ_LEN_ERR(he_dev->rbrq_head)
-				|| RBRQ_CRC_ERR(he_dev->rbrq_head)) {
-			HPRINTK("%s%s (%d.%d)\n",
-				RBRQ_CRC_ERR(he_dev->rbrq_head)
-							? "CRC_ERR " : "",
-				RBRQ_LEN_ERR(he_dev->rbrq_head)
-							? "LEN_ERR" : "",
-							vcc->vpi, vcc->vci);
-			atomic_inc(&vcc->stats->rx_err);
-			goto return_host_buffers;
-		}
-
-		skb = atm_alloc_charge(vcc, he_vcc->pdu_len + rx_skb_reserve,
-							GFP_ATOMIC);
-		if (!skb) {
-			HPRINTK("charge failed (%d.%d)\n", vcc->vpi, vcc->vci);
-			goto return_host_buffers;
-		}
-
-		if (rx_skb_reserve > 0)
-			skb_reserve(skb, rx_skb_reserve);
-
-		__net_timestamp(skb);
-
-		list_for_each_entry(heb, &he_vcc->buffers, entry)
-			skb_put_data(skb, &heb->data, heb->len);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL0:
-				/* 2.10.1.5 raw cell receive */
-				skb->len = ATM_AAL0_SDU;
-				skb_set_tail_pointer(skb, skb->len);
-				break;
-			case ATM_AAL5:
-				/* 2.10.1.2 aal5 receive */
-
-				skb->len = AAL5_LEN(skb->data, he_vcc->pdu_len);
-				skb_set_tail_pointer(skb, skb->len);
-#ifdef USE_CHECKSUM_HW
-				if (vcc->vpi == 0 && vcc->vci >= ATM_NOT_RSV_VCI) {
-					skb->ip_summed = CHECKSUM_COMPLETE;
-					skb->csum = TCP_CKSUM(skb->data,
-							he_vcc->pdu_len);
-				}
-#endif
-				break;
-		}
-
-#ifdef should_never_happen
-		if (skb->len > vcc->qos.rxtp.max_sdu)
-			hprintk("pdu_len (%d) > vcc->qos.rxtp.max_sdu (%d)!  cid 0x%x\n", skb->len, vcc->qos.rxtp.max_sdu, cid);
-#endif
-
-#ifdef notdef
-		ATM_SKB(skb)->vcc = vcc;
-#endif
-		spin_unlock(&he_dev->global_lock);
-		vcc->push(vcc, skb);
-		spin_lock(&he_dev->global_lock);
-
-		atomic_inc(&vcc->stats->rx);
-
-return_host_buffers:
-		++pdus_assembled;
-
-		list_for_each_entry_safe(heb, next, &he_vcc->buffers, entry)
-			dma_pool_free(he_dev->rbpl_pool, heb, heb->mapping);
-		INIT_LIST_HEAD(&he_vcc->buffers);
-		he_vcc->pdu_len = 0;
-
-next_rbrq_entry:
-		he_dev->rbrq_head = (struct he_rbrq *)
-				((unsigned long) he_dev->rbrq_base |
-					RBRQ_MASK(he_dev->rbrq_head + 1));
-
-	}
-	read_unlock(&vcc_sklist_lock);
-
-	if (updated) {
-		if (updated > he_dev->rbrq_peak)
-			he_dev->rbrq_peak = updated;
-
-		he_writel(he_dev, RBRQ_MASK(he_dev->rbrq_head),
-						G0_RBRQ_H + (group * 16));
-	}
-
-	return pdus_assembled;
-}
-
-static void
-he_service_tbrq(struct he_dev *he_dev, int group)
-{
-	struct he_tbrq *tbrq_tail = (struct he_tbrq *)
-				((unsigned long)he_dev->tbrq_base |
-					he_dev->hsp->group[group].tbrq_tail);
-	struct he_tpd *tpd;
-	int slot, updated = 0;
-	struct he_tpd *__tpd;
-
-	/* 2.1.6 transmit buffer return queue */
-
-	while (he_dev->tbrq_head != tbrq_tail) {
-		++updated;
-
-		HPRINTK("tbrq%d 0x%x%s%s\n",
-			group,
-			TBRQ_TPD(he_dev->tbrq_head), 
-			TBRQ_EOS(he_dev->tbrq_head) ? " EOS" : "",
-			TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : "");
-		tpd = NULL;
-		list_for_each_entry(__tpd, &he_dev->outstanding_tpds, entry) {
-			if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) {
-				tpd = __tpd;
-				list_del(&__tpd->entry);
-				break;
-			}
-		}
-
-		if (tpd == NULL) {
-			hprintk("unable to locate tpd for dma buffer %x\n",
-						TBRQ_TPD(he_dev->tbrq_head));
-			goto next_tbrq_entry;
-		}
-
-		if (TBRQ_EOS(he_dev->tbrq_head)) {
-			HPRINTK("wake_up(tx_waitq) cid 0x%x\n",
-				he_mkcid(he_dev, tpd->vcc->vpi, tpd->vcc->vci));
-			if (tpd->vcc)
-				wake_up(&HE_VCC(tpd->vcc)->tx_waitq);
-
-			goto next_tbrq_entry;
-		}
-
-		for (slot = 0; slot < TPD_MAXIOV; ++slot) {
-			if (tpd->iovec[slot].addr)
-				dma_unmap_single(&he_dev->pci_dev->dev,
-					tpd->iovec[slot].addr,
-					tpd->iovec[slot].len & TPD_LEN_MASK,
-							DMA_TO_DEVICE);
-			if (tpd->iovec[slot].len & TPD_LST)
-				break;
-				
-		}
-
-		if (tpd->skb) {	/* && !TBRQ_MULTIPLE(he_dev->tbrq_head) */
-			if (tpd->vcc && tpd->vcc->pop)
-				tpd->vcc->pop(tpd->vcc, tpd->skb);
-			else
-				dev_kfree_skb_any(tpd->skb);
-		}
-
-next_tbrq_entry:
-		if (tpd)
-			dma_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-		he_dev->tbrq_head = (struct he_tbrq *)
-				((unsigned long) he_dev->tbrq_base |
-					TBRQ_MASK(he_dev->tbrq_head + 1));
-	}
-
-	if (updated) {
-		if (updated > he_dev->tbrq_peak)
-			he_dev->tbrq_peak = updated;
-
-		he_writel(he_dev, TBRQ_MASK(he_dev->tbrq_head),
-						G0_TBRQ_H + (group * 16));
-	}
-}
-
-static void
-he_service_rbpl(struct he_dev *he_dev, int group)
-{
-	struct he_rbp *new_tail;
-	struct he_rbp *rbpl_head;
-	struct he_buff *heb;
-	dma_addr_t mapping;
-	int i;
-	int moved = 0;
-
-	rbpl_head = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
-					RBPL_MASK(he_readl(he_dev, G0_RBPL_S)));
-
-	for (;;) {
-		new_tail = (struct he_rbp *) ((unsigned long)he_dev->rbpl_base |
-						RBPL_MASK(he_dev->rbpl_tail+1));
-
-		/* table 3.42 -- rbpl_tail should never be set to rbpl_head */
-		if (new_tail == rbpl_head)
-			break;
-
-		i = find_next_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE, he_dev->rbpl_hint);
-		if (i > (RBPL_TABLE_SIZE - 1)) {
-			i = find_first_zero_bit(he_dev->rbpl_table, RBPL_TABLE_SIZE);
-			if (i > (RBPL_TABLE_SIZE - 1))
-				break;
-		}
-		he_dev->rbpl_hint = i + 1;
-
-		heb = dma_pool_alloc(he_dev->rbpl_pool, GFP_ATOMIC, &mapping);
-		if (!heb)
-			break;
-		heb->mapping = mapping;
-		list_add(&heb->entry, &he_dev->rbpl_outstanding);
-		he_dev->rbpl_virt[i] = heb;
-		set_bit(i, he_dev->rbpl_table);
-		new_tail->idx = i << RBP_IDX_OFFSET;
-		new_tail->phys = mapping + offsetof(struct he_buff, data);
-
-		he_dev->rbpl_tail = new_tail;
-		++moved;
-	} 
-
-	if (moved)
-		he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T);
-}
-
-static void
-he_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = (struct he_dev *) data;
-	int group, type;
-	int updated = 0;
-
-	HPRINTK("tasklet (0x%lx)\n", data);
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	while (he_dev->irq_head != he_dev->irq_tail) {
-		++updated;
-
-		type = ITYPE_TYPE(he_dev->irq_head->isw);
-		group = ITYPE_GROUP(he_dev->irq_head->isw);
-
-		switch (type) {
-			case ITYPE_RBRQ_THRESH:
-				HPRINTK("rbrq%d threshold\n", group);
-				fallthrough;
-			case ITYPE_RBRQ_TIMER:
-				if (he_service_rbrq(he_dev, group))
-					he_service_rbpl(he_dev, group);
-				break;
-			case ITYPE_TBRQ_THRESH:
-				HPRINTK("tbrq%d threshold\n", group);
-				fallthrough;
-			case ITYPE_TPD_COMPLETE:
-				he_service_tbrq(he_dev, group);
-				break;
-			case ITYPE_RBPL_THRESH:
-				he_service_rbpl(he_dev, group);
-				break;
-			case ITYPE_RBPS_THRESH:
-				/* shouldn't happen unless small buffers enabled */
-				break;
-			case ITYPE_PHY:
-				HPRINTK("phy interrupt\n");
-#ifdef CONFIG_ATM_HE_USE_SUNI
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-				if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->interrupt)
-					he_dev->atm_dev->phy->interrupt(he_dev->atm_dev);
-				spin_lock_irqsave(&he_dev->global_lock, flags);
-#endif
-				break;
-			case ITYPE_OTHER:
-				switch (type|group) {
-					case ITYPE_PARITY:
-						hprintk("parity error\n");
-						break;
-					case ITYPE_ABORT:
-						hprintk("abort 0x%x\n", he_readl(he_dev, ABORT_ADDR));
-						break;
-				}
-				break;
-			case ITYPE_TYPE(ITYPE_INVALID):
-				/* see 8.1.1 -- check all queues */
-
-				HPRINTK("isw not updated 0x%x\n", he_dev->irq_head->isw);
-
-				he_service_rbrq(he_dev, 0);
-				he_service_rbpl(he_dev, 0);
-				he_service_tbrq(he_dev, 0);
-				break;
-			default:
-				hprintk("bad isw 0x%x?\n", he_dev->irq_head->isw);
-		}
-
-		he_dev->irq_head->isw = ITYPE_INVALID;
-
-		he_dev->irq_head = (struct he_irq *) NEXT_ENTRY(he_dev->irq_base, he_dev->irq_head, IRQ_MASK);
-	}
-
-	if (updated) {
-		if (updated > he_dev->irq_peak)
-			he_dev->irq_peak = updated;
-
-		he_writel(he_dev,
-			IRQ_SIZE(CONFIG_IRQ_SIZE) |
-			IRQ_THRESH(CONFIG_IRQ_THRESH) |
-			IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD);
-		(void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata; flush posted writes */
-	}
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-}
-
-static irqreturn_t
-he_irq_handler(int irq, void *dev_id)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = (struct he_dev * )dev_id;
-	int handled = 0;
-
-	if (he_dev == NULL)
-		return IRQ_NONE;
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	he_dev->irq_tail = (struct he_irq *) (((unsigned long)he_dev->irq_base) |
-						(*he_dev->irq_tailoffset << 2));
-
-	if (he_dev->irq_tail == he_dev->irq_head) {
-		HPRINTK("tailoffset not updated?\n");
-		he_dev->irq_tail = (struct he_irq *) ((unsigned long)he_dev->irq_base |
-			((he_readl(he_dev, IRQ0_BASE) & IRQ_MASK) << 2));
-		(void) he_readl(he_dev, INT_FIFO);	/* 8.1.2 controller errata */
-	}
-
-#ifdef DEBUG
-	if (he_dev->irq_head == he_dev->irq_tail /* && !IRQ_PENDING */)
-		hprintk("spurious (or shared) interrupt?\n");
-#endif
-
-	if (he_dev->irq_head != he_dev->irq_tail) {
-		handled = 1;
-		tasklet_schedule(&he_dev->tasklet);
-		he_writel(he_dev, INT_CLEAR_A, INT_FIFO);	/* clear interrupt */
-		(void) he_readl(he_dev, INT_FIFO);		/* flush posted writes */
-	}
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	return IRQ_RETVAL(handled);
-
-}
-
-static __inline__ void
-__enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid)
-{
-	struct he_tpdrq *new_tail;
-
-	HPRINTK("tpdrq %p cid 0x%x -> tpdrq_tail %p\n",
-					tpd, cid, he_dev->tpdrq_tail);
-
-	/* new_tail = he_dev->tpdrq_tail; */
-	new_tail = (struct he_tpdrq *) ((unsigned long) he_dev->tpdrq_base |
-					TPDRQ_MASK(he_dev->tpdrq_tail+1));
-
-	/*
-	 * check to see if we are about to set the tail == head
-	 * if true, update the head pointer from the adapter
-	 * to see if this is really the case (reading the queue
-	 * head for every enqueue would be unnecessarily slow)
-	 */
-
-	if (new_tail == he_dev->tpdrq_head) {
-		he_dev->tpdrq_head = (struct he_tpdrq *)
-			(((unsigned long)he_dev->tpdrq_base) |
-				TPDRQ_MASK(he_readl(he_dev, TPDRQ_B_H)));
-
-		if (new_tail == he_dev->tpdrq_head) {
-			int slot;
-
-			hprintk("tpdrq full (cid 0x%x)\n", cid);
-			/*
-			 * FIXME
-			 * push tpd onto a transmit backlog queue
-			 * after service_tbrq, service the backlog
-			 * for now, we just drop the pdu
-			 */
-			for (slot = 0; slot < TPD_MAXIOV; ++slot) {
-				if (tpd->iovec[slot].addr)
-					dma_unmap_single(&he_dev->pci_dev->dev,
-						tpd->iovec[slot].addr,
-						tpd->iovec[slot].len & TPD_LEN_MASK,
-								DMA_TO_DEVICE);
-			}
-			if (tpd->skb) {
-				if (tpd->vcc->pop)
-					tpd->vcc->pop(tpd->vcc, tpd->skb);
-				else
-					dev_kfree_skb_any(tpd->skb);
-				atomic_inc(&tpd->vcc->stats->tx_err);
-			}
-			dma_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
-			return;
-		}
-	}
-
-	/* 2.1.5 transmit packet descriptor ready queue */
-	list_add_tail(&tpd->entry, &he_dev->outstanding_tpds);
-	he_dev->tpdrq_tail->tpd = TPD_ADDR(tpd->status);
-	he_dev->tpdrq_tail->cid = cid;
-	wmb();
-
-	he_dev->tpdrq_tail = new_tail;
-
-	he_writel(he_dev, TPDRQ_MASK(he_dev->tpdrq_tail), TPDRQ_T);
-	(void) he_readl(he_dev, TPDRQ_T);		/* flush posted writes */
-}
-
-static int
-he_open(struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	struct he_vcc *he_vcc;
-	int err = 0;
-	unsigned cid, rsr0, rsr1, rsr4, tsr0, tsr0_aal, tsr4, period, reg, clock;
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
-		return 0;
-
-	HPRINTK("open vcc %p %d.%d\n", vcc, vpi, vci);
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	cid = he_mkcid(he_dev, vpi, vci);
-
-	he_vcc = kmalloc_obj(struct he_vcc, GFP_ATOMIC);
-	if (he_vcc == NULL) {
-		hprintk("unable to allocate he_vcc during open\n");
-		return -ENOMEM;
-	}
-
-	INIT_LIST_HEAD(&he_vcc->buffers);
-	he_vcc->pdu_len = 0;
-	he_vcc->rc_index = -1;
-
-	init_waitqueue_head(&he_vcc->rx_waitq);
-	init_waitqueue_head(&he_vcc->tx_waitq);
-
-	vcc->dev_data = he_vcc;
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		int pcr_goal;
-
-		pcr_goal = atm_pcr_goal(&vcc->qos.txtp);
-		if (pcr_goal == 0)
-			pcr_goal = he_dev->atm_dev->link_rate;
-		if (pcr_goal < 0)	/* means round down, technically */
-			pcr_goal = -pcr_goal;
-
-		HPRINTK("open tx cid 0x%x pcr_goal %d\n", cid, pcr_goal);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL5:
-				tsr0_aal = TSR0_AAL5;
-				tsr4 = TSR4_AAL5;
-				break;
-			case ATM_AAL0:
-				tsr0_aal = TSR0_AAL0_SDU;
-				tsr4 = TSR4_AAL0_SDU;
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		tsr0 = he_readl_tsr0(he_dev, cid);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		if (TSR0_CONN_STATE(tsr0) != 0) {
-			hprintk("cid 0x%x not idle (tsr0 = 0x%x)\n", cid, tsr0);
-			err = -EBUSY;
-			goto open_failed;
-		}
-
-		switch (vcc->qos.txtp.traffic_class) {
-			case ATM_UBR:
-				/* 2.3.3.1 open connection ubr */
-
-				tsr0 = TSR0_UBR | TSR0_GROUP(0) | tsr0_aal |
-					TSR0_USE_WMIN | TSR0_UPDATE_GER;
-				break;
-
-			case ATM_CBR:
-				/* 2.3.3.2 open connection cbr */
-
-				/* 8.2.3 cbr scheduler wrap problem -- limit to 90% total link rate */
-				if ((he_dev->total_bw + pcr_goal)
-					> (he_dev->atm_dev->link_rate * 9 / 10))
-				{
-					err = -EBUSY;
-					goto open_failed;
-				}
-
-				spin_lock_irqsave(&he_dev->global_lock, flags);			/* also protects he_dev->cs_stper[] */
-
-				/* find an unused cs_stper register */
-				for (reg = 0; reg < HE_NUM_CS_STPER; ++reg)
-					if (he_dev->cs_stper[reg].inuse == 0 || 
-					    he_dev->cs_stper[reg].pcr == pcr_goal)
-							break;
-
-				if (reg == HE_NUM_CS_STPER) {
-					err = -EBUSY;
-					spin_unlock_irqrestore(&he_dev->global_lock, flags);
-					goto open_failed;
-				}
-
-				he_dev->total_bw += pcr_goal;
-
-				he_vcc->rc_index = reg;
-				++he_dev->cs_stper[reg].inuse;
-				he_dev->cs_stper[reg].pcr = pcr_goal;
-
-				clock = he_is622(he_dev) ? 66667000 : 50000000;
-				period = clock / pcr_goal;
-				
-				HPRINTK("rc_index = %d period = %d\n",
-								reg, period);
-
-				he_writel_mbox(he_dev, rate_to_atmf(period/2),
-							CS_STPER0 + reg);
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-				tsr0 = TSR0_CBR | TSR0_GROUP(0) | tsr0_aal |
-							TSR0_RC_INDEX(reg);
-
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		he_writel_tsr0(he_dev, tsr0, cid);
-		he_writel_tsr4(he_dev, tsr4 | 1, cid);
-		he_writel_tsr1(he_dev, TSR1_MCR(rate_to_atmf(0)) |
-					TSR1_PCR(rate_to_atmf(pcr_goal)), cid);
-		he_writel_tsr2(he_dev, TSR2_ACR(rate_to_atmf(pcr_goal)), cid);
-		he_writel_tsr9(he_dev, TSR9_OPEN_CONN, cid);
-
-		he_writel_tsr3(he_dev, 0x0, cid);
-		he_writel_tsr5(he_dev, 0x0, cid);
-		he_writel_tsr6(he_dev, 0x0, cid);
-		he_writel_tsr7(he_dev, 0x0, cid);
-		he_writel_tsr8(he_dev, 0x0, cid);
-		he_writel_tsr10(he_dev, 0x0, cid);
-		he_writel_tsr11(he_dev, 0x0, cid);
-		he_writel_tsr12(he_dev, 0x0, cid);
-		he_writel_tsr13(he_dev, 0x0, cid);
-		he_writel_tsr14(he_dev, 0x0, cid);
-		(void) he_readl_tsr0(he_dev, cid);		/* flush posted writes */
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	}
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		unsigned aal;
-
-		HPRINTK("open rx cid 0x%x (rx_waitq %p)\n", cid,
-		 				&HE_VCC(vcc)->rx_waitq);
-
-		switch (vcc->qos.aal) {
-			case ATM_AAL5:
-				aal = RSR0_AAL5;
-				break;
-			case ATM_AAL0:
-				aal = RSR0_RAWCELL;
-				break;
-			default:
-				err = -EINVAL;
-				goto open_failed;
-		}
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		rsr0 = he_readl_rsr0(he_dev, cid);
-		if (rsr0 & RSR0_OPEN_CONN) {
-			spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-			hprintk("cid 0x%x not idle (rsr0 = 0x%x)\n", cid, rsr0);
-			err = -EBUSY;
-			goto open_failed;
-		}
-
-		rsr1 = RSR1_GROUP(0) | RSR1_RBPL_ONLY;
-		rsr4 = RSR4_GROUP(0) | RSR4_RBPL_ONLY;
-		rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? 
-				(RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0;
-
-#ifdef USE_CHECKSUM_HW
-		if (vpi == 0 && vci >= ATM_NOT_RSV_VCI)
-			rsr0 |= RSR0_TCP_CKSUM;
-#endif
-
-		he_writel_rsr4(he_dev, rsr4, cid);
-		he_writel_rsr1(he_dev, rsr1, cid);
-		/* 5.1.11 last parameter initialized should be
-			  the open/closed indication in rsr0 */
-		he_writel_rsr0(he_dev,
-			rsr0 | RSR0_START_PDU | RSR0_OPEN_CONN | aal, cid);
-		(void) he_readl_rsr0(he_dev, cid);		/* flush posted writes */
-
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-	}
-
-open_failed:
-
-	if (err) {
-		kfree(he_vcc);
-		clear_bit(ATM_VF_ADDR, &vcc->flags);
-	}
-	else
-		set_bit(ATM_VF_READY, &vcc->flags);
-
-	return err;
-}
-
-static void
-he_close(struct atm_vcc *vcc)
-{
-	unsigned long flags;
-	DECLARE_WAITQUEUE(wait, current);
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	struct he_tpd *tpd;
-	unsigned cid;
-	struct he_vcc *he_vcc = HE_VCC(vcc);
-#define MAX_RETRY 30
-	int retry = 0, sleep = 1, tx_inuse;
-
-	HPRINTK("close vcc %p %d.%d\n", vcc, vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-	cid = he_mkcid(he_dev, vcc->vpi, vcc->vci);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		int timeout;
-
-		HPRINTK("close rx cid 0x%x\n", cid);
-
-		/* 2.7.2.2 close receive operation */
-
-		/* wait for previous close (if any) to finish */
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		while (he_readl(he_dev, RCC_STAT) & RCC_BUSY) {
-			HPRINTK("close cid 0x%x RCC_BUSY\n", cid);
-			udelay(250);
-		}
-
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&he_vcc->rx_waitq, &wait);
-
-		he_writel_rsr0(he_dev, RSR0_CLOSE_CONN, cid);
-		(void) he_readl_rsr0(he_dev, cid);		/* flush posted writes */
-		he_writel_mbox(he_dev, cid, RXCON_CLOSE);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		timeout = schedule_timeout(30*HZ);
-
-		remove_wait_queue(&he_vcc->rx_waitq, &wait);
-		set_current_state(TASK_RUNNING);
-
-		if (timeout == 0)
-			hprintk("close rx timeout cid 0x%x\n", cid);
-
-		HPRINTK("close rx cid 0x%x complete\n", cid);
-
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		volatile unsigned tsr4, tsr0;
-		int timeout;
-
-		HPRINTK("close tx cid 0x%x\n", cid);
-		
-		/* 2.1.2
-		 *
-		 * ... the host must first stop queueing packets to the TPDRQ
-		 * on the connection to be closed, then wait for all outstanding
-		 * packets to be transmitted and their buffers returned to the
-		 * TBRQ. When the last packet on the connection arrives in the
-		 * TBRQ, the host issues the close command to the adapter.
-		 */
-
-		while (((tx_inuse = refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) > 1) &&
-		       (retry < MAX_RETRY)) {
-			msleep(sleep);
-			if (sleep < 250)
-				sleep = sleep * 2;
-
-			++retry;
-		}
-
-		if (tx_inuse > 1)
-			hprintk("close tx cid 0x%x tx_inuse = %d\n", cid, tx_inuse);
-
-		/* 2.3.1.1 generic close operations with flush */
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-		he_writel_tsr4_upper(he_dev, TSR4_FLUSH_CONN, cid);
-					/* also clears TSR4_SESSION_ENDED */
-
-		switch (vcc->qos.txtp.traffic_class) {
-			case ATM_UBR:
-				he_writel_tsr1(he_dev, 
-					TSR1_MCR(rate_to_atmf(200000))
-					| TSR1_PCR(0), cid);
-				break;
-			case ATM_CBR:
-				he_writel_tsr14_upper(he_dev, TSR14_DELETE, cid);
-				break;
-		}
-		(void) he_readl_tsr4(he_dev, cid);		/* flush posted writes */
-
-		tpd = __alloc_tpd(he_dev);
-		if (tpd == NULL) {
-			hprintk("close tx he_alloc_tpd failed cid 0x%x\n", cid);
-			goto close_tx_incomplete;
-		}
-		tpd->status |= TPD_EOS | TPD_INT;
-		tpd->skb = NULL;
-		tpd->vcc = vcc;
-		wmb();
-
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&he_vcc->tx_waitq, &wait);
-		__enqueue_tpd(he_dev, tpd, cid);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		timeout = schedule_timeout(30*HZ);
-
-		remove_wait_queue(&he_vcc->tx_waitq, &wait);
-		set_current_state(TASK_RUNNING);
-
-		spin_lock_irqsave(&he_dev->global_lock, flags);
-
-		if (timeout == 0) {
-			hprintk("close tx timeout cid 0x%x\n", cid);
-			goto close_tx_incomplete;
-		}
-
-		while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
-			HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
-			udelay(250);
-		}
-
-		while (TSR0_CONN_STATE(tsr0 = he_readl_tsr0(he_dev, cid)) != 0) {
-			HPRINTK("close tx cid 0x%x TSR0_CONN_STATE != 0 (tsr0 = 0x%x)\n", cid, tsr0);
-			udelay(250);
-		}
-
-close_tx_incomplete:
-
-		if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-			int reg = he_vcc->rc_index;
-
-			HPRINTK("cs_stper reg = %d\n", reg);
-
-			if (he_dev->cs_stper[reg].inuse == 0)
-				hprintk("cs_stper[%d].inuse = 0!\n", reg);
-			else
-				--he_dev->cs_stper[reg].inuse;
-
-			he_dev->total_bw -= he_dev->cs_stper[reg].pcr;
-		}
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-		HPRINTK("close tx cid 0x%x complete\n", cid);
-	}
-
-	kfree(he_vcc);
-
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-}
-
-static int
-he_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(vcc->dev);
-	unsigned cid = he_mkcid(he_dev, vcc->vpi, vcc->vci);
-	struct he_tpd *tpd;
-#ifdef USE_SCATTERGATHER
-	int i, slot = 0;
-#endif
-
-#define HE_TPD_BUFSIZE 0xffff
-
-	HPRINTK("send %d.%d\n", vcc->vpi, vcc->vci);
-
-	if ((skb->len > HE_TPD_BUFSIZE) ||
-	    ((vcc->qos.aal == ATM_AAL0) && (skb->len != ATM_AAL0_SDU))) {
-		hprintk("buffer too large (or small) -- %d bytes\n", skb->len );
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -EINVAL;
-	}
-
-#ifndef USE_SCATTERGATHER
-	if (skb_shinfo(skb)->nr_frags) {
-		hprintk("no scatter/gather support\n");
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		return -EINVAL;
-	}
-#endif
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-
-	tpd = __alloc_tpd(he_dev);
-	if (tpd == NULL) {
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb_any(skb);
-		atomic_inc(&vcc->stats->tx_err);
-		spin_unlock_irqrestore(&he_dev->global_lock, flags);
-		return -ENOMEM;
-	}
-
-	if (vcc->qos.aal == ATM_AAL5)
-		tpd->status |= TPD_CELLTYPE(TPD_USERCELL);
-	else {
-		char *pti_clp = (void *) (skb->data + 3);
-		int clp, pti;
-
-		pti = (*pti_clp & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT; 
-		clp = (*pti_clp & ATM_HDR_CLP);
-		tpd->status |= TPD_CELLTYPE(pti);
-		if (clp)
-			tpd->status |= TPD_CLP;
-
-		skb_pull(skb, ATM_AAL0_SDU - ATM_CELL_PAYLOAD);
-	}
-
-#ifdef USE_SCATTERGATHER
-	tpd->iovec[slot].addr = dma_map_single(&he_dev->pci_dev->dev, skb->data,
-				skb_headlen(skb), DMA_TO_DEVICE);
-	tpd->iovec[slot].len = skb_headlen(skb);
-	++slot;
-
-	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-		if (slot == TPD_MAXIOV) {	/* queue tpd; start new tpd */
-			tpd->vcc = vcc;
-			tpd->skb = NULL;	/* not the last fragment
-						   so dont ->push() yet */
-			wmb();
-
-			__enqueue_tpd(he_dev, tpd, cid);
-			tpd = __alloc_tpd(he_dev);
-			if (tpd == NULL) {
-				if (vcc->pop)
-					vcc->pop(vcc, skb);
-				else
-					dev_kfree_skb_any(skb);
-				atomic_inc(&vcc->stats->tx_err);
-				spin_unlock_irqrestore(&he_dev->global_lock, flags);
-				return -ENOMEM;
-			}
-			tpd->status |= TPD_USERCELL;
-			slot = 0;
-		}
-
-		tpd->iovec[slot].addr = skb_frag_dma_map(&he_dev->pci_dev->dev,
-				frag, 0, skb_frag_size(frag), DMA_TO_DEVICE);
-		tpd->iovec[slot].len = skb_frag_size(frag);
-		++slot;
-
-	}
-
-	tpd->iovec[slot - 1].len |= TPD_LST;
-#else
-	tpd->address0 = dma_map_single(&he_dev->pci_dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
-	tpd->length0 = skb->len | TPD_LST;
-#endif
-	tpd->status |= TPD_INT;
-
-	tpd->vcc = vcc;
-	tpd->skb = skb;
-	wmb();
-	ATM_SKB(skb)->vcc = vcc;
-
-	__enqueue_tpd(he_dev, tpd, cid);
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int
-he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-	struct he_ioctl_reg reg;
-	int err = 0;
-
-	switch (cmd) {
-		case HE_GET_REG:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-
-			if (copy_from_user(&reg, arg,
-					   sizeof(struct he_ioctl_reg)))
-				return -EFAULT;
-
-			spin_lock_irqsave(&he_dev->global_lock, flags);
-			switch (reg.type) {
-				case HE_REGTYPE_PCI:
-					if (reg.addr >= HE_REGMAP_SIZE) {
-						err = -EINVAL;
-						break;
-					}
-
-					reg.val = he_readl(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_RCM:
-					reg.val =
-						he_readl_rcm(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_TCM:
-					reg.val =
-						he_readl_tcm(he_dev, reg.addr);
-					break;
-				case HE_REGTYPE_MBOX:
-					reg.val =
-						he_readl_mbox(he_dev, reg.addr);
-					break;
-				default:
-					err = -EINVAL;
-					break;
-			}
-			spin_unlock_irqrestore(&he_dev->global_lock, flags);
-			if (err == 0)
-				if (copy_to_user(arg, &reg,
-							sizeof(struct he_ioctl_reg)))
-					return -EFAULT;
-			break;
-		default:
-#ifdef CONFIG_ATM_HE_USE_SUNI
-			if (atm_dev->phy && atm_dev->phy->ioctl)
-				err = atm_dev->phy->ioctl(atm_dev, cmd, arg);
-#else /* CONFIG_ATM_HE_USE_SUNI */
-			err = -EINVAL;
-#endif /* CONFIG_ATM_HE_USE_SUNI */
-			break;
-	}
-
-	return err;
-}
-
-static void
-he_phy_put(struct atm_dev *atm_dev, unsigned char val, unsigned long addr)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-
-	HPRINTK("phy_put(val 0x%x, addr 0x%lx)\n", val, addr);
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	he_writel(he_dev, val, FRAMER + (addr*4));
-	(void) he_readl(he_dev, FRAMER + (addr*4));		/* flush posted writes */
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-}
- 
-	
-static unsigned char
-he_phy_get(struct atm_dev *atm_dev, unsigned long addr)
-{ 
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(atm_dev);
-	unsigned reg;
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	reg = he_readl(he_dev, FRAMER + (addr*4));
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	HPRINTK("phy_get(addr 0x%lx) =0x%x\n", addr, reg);
-	return reg;
-}
-
-static int
-he_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
-{
-	unsigned long flags;
-	struct he_dev *he_dev = HE_DEV(dev);
-	int left, i;
-#ifdef notdef
-	struct he_rbrq *rbrq_tail;
-	struct he_tpdrq *tpdrq_head;
-	int rbpl_head, rbpl_tail;
-#endif
-	static long mcc = 0, oec = 0, dcc = 0, cec = 0;
-
-
-	left = *pos;
-	if (!left--)
-		return sprintf(page, "ATM he driver\n");
-
-	if (!left--)
-		return sprintf(page, "%s%s\n\n",
-			he_dev->prod_id, he_dev->media & 0x40 ? "SM" : "MM");
-
-	if (!left--)
-		return sprintf(page, "Mismatched Cells  VPI/VCI Not Open  Dropped Cells  RCM Dropped Cells\n");
-
-	spin_lock_irqsave(&he_dev->global_lock, flags);
-	mcc += he_readl(he_dev, MCC);
-	oec += he_readl(he_dev, OEC);
-	dcc += he_readl(he_dev, DCC);
-	cec += he_readl(he_dev, CEC);
-	spin_unlock_irqrestore(&he_dev->global_lock, flags);
-
-	if (!left--)
-		return sprintf(page, "%16ld  %16ld  %13ld  %17ld\n\n", 
-							mcc, oec, dcc, cec);
-
-	if (!left--)
-		return sprintf(page, "irq_size = %d  inuse = ?  peak = %d\n",
-				CONFIG_IRQ_SIZE, he_dev->irq_peak);
-
-	if (!left--)
-		return sprintf(page, "tpdrq_size = %d  inuse = ?\n",
-						CONFIG_TPDRQ_SIZE);
-
-	if (!left--)
-		return sprintf(page, "rbrq_size = %d  inuse = ?  peak = %d\n",
-				CONFIG_RBRQ_SIZE, he_dev->rbrq_peak);
-
-	if (!left--)
-		return sprintf(page, "tbrq_size = %d  peak = %d\n",
-					CONFIG_TBRQ_SIZE, he_dev->tbrq_peak);
-
-
-#ifdef notdef
-	rbpl_head = RBPL_MASK(he_readl(he_dev, G0_RBPL_S));
-	rbpl_tail = RBPL_MASK(he_readl(he_dev, G0_RBPL_T));
-
-	inuse = rbpl_head - rbpl_tail;
-	if (inuse < 0)
-		inuse += CONFIG_RBPL_SIZE * sizeof(struct he_rbp);
-	inuse /= sizeof(struct he_rbp);
-
-	if (!left--)
-		return sprintf(page, "rbpl_size = %d  inuse = %d\n\n",
-						CONFIG_RBPL_SIZE, inuse);
-#endif
-
-	if (!left--)
-		return sprintf(page, "rate controller periods (cbr)\n                 pcr  #vc\n");
-
-	for (i = 0; i < HE_NUM_CS_STPER; ++i)
-		if (!left--)
-			return sprintf(page, "cs_stper%-2d  %8ld  %3d\n", i,
-						he_dev->cs_stper[i].pcr,
-						he_dev->cs_stper[i].inuse);
-
-	if (!left--)
-		return sprintf(page, "total bw (cbr): %d  (limit %d)\n",
-			he_dev->total_bw, he_dev->atm_dev->link_rate * 10 / 9);
-
-	return 0;
-}
-
-/* eeprom routines  -- see 4.7 */
-
-static u8 read_prom_byte(struct he_dev *he_dev, int addr)
-{
-	u32 val = 0, tmp_read = 0;
-	int i, j = 0;
-	u8 byte_read = 0;
-
-	val = readl(he_dev->membase + HOST_CNTL);
-	val &= 0xFFFFE0FF;
-       
-	/* Turn on write enable */
-	val |= 0x800;
-	he_writel(he_dev, val, HOST_CNTL);
-       
-	/* Send READ instruction */
-	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
-		he_writel(he_dev, val | readtab[i], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	/* Next, we need to send the byte address to read from */
-	for (i = 7; i >= 0; i--) {
-		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
-		udelay(EEPROM_DELAY);
-		he_writel(he_dev, val | clocktab[j++] | (((addr >> i) & 1) << 9), HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	j = 0;
-
-	val &= 0xFFFFF7FF;      /* Turn off write enable */
-	he_writel(he_dev, val, HOST_CNTL);
-       
-	/* Now, we can read data from the EEPROM by clocking it in */
-	for (i = 7; i >= 0; i--) {
-		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-		tmp_read = he_readl(he_dev, HOST_CNTL);
-		byte_read |= (unsigned char)
-			   ((tmp_read & ID_DOUT) >> ID_DOFFSET << i);
-		he_writel(he_dev, val | clocktab[j++], HOST_CNTL);
-		udelay(EEPROM_DELAY);
-	}
-       
-	he_writel(he_dev, val | ID_CS, HOST_CNTL);
-	udelay(EEPROM_DELAY);
-
-	return byte_read;
-}
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
-MODULE_DESCRIPTION("ForeRunnerHE ATM Adapter driver");
-module_param(disable64, bool, 0);
-MODULE_PARM_DESC(disable64, "disable 64-bit pci bus transfers");
-module_param(nvpibits, short, 0);
-MODULE_PARM_DESC(nvpibits, "numbers of bits for vpi (default 0)");
-module_param(nvcibits, short, 0);
-MODULE_PARM_DESC(nvcibits, "numbers of bits for vci (default 12)");
-module_param(rx_skb_reserve, short, 0);
-MODULE_PARM_DESC(rx_skb_reserve, "padding for receive skb (default 16)");
-module_param(irq_coalesce, bool, 0);
-MODULE_PARM_DESC(irq_coalesce, "use interrupt coalescing (default 1)");
-module_param(sdh, bool, 0);
-MODULE_PARM_DESC(sdh, "use SDH framing (default 0)");
-
-static const struct pci_device_id he_pci_tbl[] = {
-	{ PCI_VDEVICE(FORE, PCI_DEVICE_ID_FORE_HE), 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, he_pci_tbl);
-
-static struct pci_driver he_driver = {
-	.name =		"he",
-	.probe =	he_init_one,
-	.remove =	he_remove_one,
-	.id_table =	he_pci_tbl,
-};
-
-module_pci_driver(he_driver);
diff --git a/drivers/atm/he.h b/drivers/atm/he.h
deleted file mode 100644
index f3f5367..0000000
--- a/drivers/atm/he.h
+++ /dev/null
@@ -1,845 +0,0 @@
-/*
-
-  he.h
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2001  Naval Research Laboratory
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library 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
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/*
-
-  he.h
-
-  ForeRunnerHE ATM Adapter driver for ATM on Linux
-  Copyright (C) 1999-2000  Naval Research Laboratory
-
-  Permission to use, copy, modify and distribute this software and its
-  documentation is hereby granted, provided that both the copyright
-  notice and this permission notice appear in all copies of the software,
-  derivative works or modified versions, and any portions thereof, and
-  that both notices appear in supporting documentation.
-
-  NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
-  DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
-  RESULTING FROM THE USE OF THIS SOFTWARE.
-
- */
-
-#ifndef _HE_H_
-#define _HE_H_
-
-#define DEV_LABEL       "he"
-
-#define CONFIG_DEFAULT_VCIBITS	12
-#define CONFIG_DEFAULT_VPIBITS	0
-
-#define CONFIG_IRQ_SIZE		128
-#define CONFIG_IRQ_THRESH	(CONFIG_IRQ_SIZE/2)
-
-#define CONFIG_TPDRQ_SIZE	512
-#define TPDRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1))
-
-#define CONFIG_RBRQ_SIZE	512
-#define CONFIG_RBRQ_THRESH	400
-#define RBRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_RBRQ_SIZE<<3)-1))
-
-#define CONFIG_TBRQ_SIZE	512
-#define CONFIG_TBRQ_THRESH	400
-#define TBRQ_MASK(x)		(((unsigned long)(x))&((CONFIG_TBRQ_SIZE<<2)-1))
-
-#define CONFIG_RBPL_SIZE	512
-#define CONFIG_RBPL_THRESH	64
-#define CONFIG_RBPL_BUFSIZE	4096
-#define RBPL_MASK(x)		(((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1))
-
-/* 5.1.3 initialize connection memory */
-
-#define CONFIG_RSRA		0x00000
-#define CONFIG_RCMLBM		0x08000
-#define CONFIG_RCMABR		0x0d800
-#define CONFIG_RSRB		0x0e000
-
-#define CONFIG_TSRA		0x00000
-#define CONFIG_TSRB		0x08000
-#define CONFIG_TSRC		0x0c000
-#define CONFIG_TSRD		0x0e000
-#define CONFIG_TMABR		0x0f000
-#define CONFIG_TPDBA		0x10000
-
-#define HE_MAXCIDBITS		12
-
-/* 2.9.3.3 interrupt encodings */
-
-struct he_irq {
-	volatile u32 isw;
-};
-
-#define IRQ_ALIGNMENT		0x1000
-
-#define NEXT_ENTRY(base, tail, mask) \
-				(((unsigned long)base)|(((unsigned long)(tail+1))&mask))
-
-#define ITYPE_INVALID		0xffffffff
-#define ITYPE_TBRQ_THRESH	(0<<3)
-#define ITYPE_TPD_COMPLETE	(1<<3)
-#define ITYPE_RBPS_THRESH	(2<<3)
-#define ITYPE_RBPL_THRESH	(3<<3)
-#define ITYPE_RBRQ_THRESH	(4<<3)
-#define ITYPE_RBRQ_TIMER	(5<<3)
-#define ITYPE_PHY		(6<<3)
-#define ITYPE_OTHER		0x80
-#define ITYPE_PARITY		0x81
-#define ITYPE_ABORT		0x82
-
-#define ITYPE_GROUP(x)		(x & 0x7)
-#define ITYPE_TYPE(x)		(x & 0xf8)
-
-#define HE_NUM_GROUPS 8
-
-/* 2.1.4 transmit packet descriptor */
-
-struct he_tpd {
-
-	/* read by the adapter */
-
-	volatile u32 status;
-	volatile u32 reserved;
-
-#define TPD_MAXIOV	3
-	struct {
-		u32 addr, len;
-	} iovec[TPD_MAXIOV];
-
-#define address0 iovec[0].addr
-#define length0 iovec[0].len
-
-	/* linux-atm extensions */
-
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	struct list_head entry;
-};
-
-#define TPD_ALIGNMENT	64
-#define TPD_LEN_MASK	0xffff
-
-#define TPD_ADDR_SHIFT  6
-#define TPD_MASK	0xffffffc0
-#define TPD_ADDR(x)	((x) & TPD_MASK)
-#define TPD_INDEX(x)	(TPD_ADDR(x) >> TPD_ADDR_SHIFT)
-
-
-/* table 2.3 transmit buffer return elements */
-
-struct he_tbrq {
-	volatile u32 tbre;
-};
-
-#define TBRQ_ALIGNMENT	CONFIG_TBRQ_SIZE
-
-#define TBRQ_TPD(tbrq)		((tbrq)->tbre & 0xffffffc0)
-#define TBRQ_EOS(tbrq)		((tbrq)->tbre & (1<<3))
-#define TBRQ_MULTIPLE(tbrq)	((tbrq)->tbre & (1))
-
-/* table 2.21 receive buffer return queue element field organization */
-
-struct he_rbrq {
-	volatile u32 addr;
-	volatile u32 cidlen;
-};
-
-#define RBRQ_ALIGNMENT	CONFIG_RBRQ_SIZE
-
-#define RBRQ_ADDR(rbrq)		((rbrq)->addr & 0xffffffc0)
-#define RBRQ_CRC_ERR(rbrq)	((rbrq)->addr & (1<<5))
-#define RBRQ_LEN_ERR(rbrq)	((rbrq)->addr & (1<<4))
-#define RBRQ_END_PDU(rbrq)	((rbrq)->addr & (1<<3))
-#define RBRQ_AAL5_PROT(rbrq)	((rbrq)->addr & (1<<2))
-#define RBRQ_CON_CLOSED(rbrq)	((rbrq)->addr & (1<<1))
-#define RBRQ_HBUF_ERR(rbrq)	((rbrq)->addr & 1)
-#define RBRQ_CID(rbrq)		(((rbrq)->cidlen >> 16) & 0x1fff)
-#define RBRQ_BUFLEN(rbrq)	((rbrq)->cidlen & 0xffff)
-
-/* figure 2.3 transmit packet descriptor ready queue */
-
-struct he_tpdrq {
-	volatile u32 tpd;
-	volatile u32 cid;
-};
-
-#define TPDRQ_ALIGNMENT CONFIG_TPDRQ_SIZE
-
-/* table 2.30 host status page detail */
-
-#define HSP_ALIGNMENT	0x400		/* must align on 1k boundary */
-
-struct he_hsp {
-	struct he_hsp_entry {
-		volatile u32 tbrq_tail; 
-		volatile u32 reserved1[15];
-		volatile u32 rbrq_tail; 
-		volatile u32 reserved2[15];
-	} group[HE_NUM_GROUPS];
-};
-
-/*
- * figure 2.9 receive buffer pools
- *
- * since a virtual address might be more than 32 bits, we store an index
- * in the virt member of he_rbp.  NOTE: the lower six bits in the  rbrq
- * addr member are used for buffer status further limiting us to 26 bits.
- */
-
-struct he_rbp {
-	volatile u32 phys;
-	volatile u32 idx;	/* virt */
-};
-
-#define RBP_IDX_OFFSET 6
-
-/*
- * the he dma engine will try to hold an extra 16 buffers in its local
- * caches.  and add a couple buffers for safety.
- */
-
-#define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
-
-struct he_buff {
-	struct list_head entry;
-	dma_addr_t mapping;
-	unsigned long len;
-	u8 data[];
-};
-
-#ifdef notyet
-struct he_group {
-	u32 rpbl_size, rpbl_qsize;
-	struct he_rpb_entry *rbpl_ba;
-};
-#endif
-
-#define HE_LOOKUP_VCC(dev, cid) ((dev)->he_vcc_table[(cid)].vcc)
-
-struct he_vcc_table 
-{
-	struct atm_vcc *vcc;
-};
-
-struct he_cs_stper
-{
-	long pcr;
-	int inuse;
-};
-
-#define HE_NUM_CS_STPER		16
-
-struct he_dev {
-	unsigned int number;
-	unsigned int irq;
-	void __iomem *membase;
-
-	char prod_id[30];
-	char mac_addr[6];
-	int media;
-
-	unsigned int vcibits, vpibits;
-	unsigned int cells_per_row;
-	unsigned int bytes_per_row;
-	unsigned int cells_per_lbuf;
-	unsigned int r0_numrows, r0_startrow, r0_numbuffs;
-	unsigned int r1_numrows, r1_startrow, r1_numbuffs;
-	unsigned int tx_numrows, tx_startrow, tx_numbuffs;
-	unsigned int buffer_limit;
-
-	struct he_vcc_table *he_vcc_table;
-
-#ifdef notyet
-	struct he_group group[HE_NUM_GROUPS];
-#endif
-	struct he_cs_stper cs_stper[HE_NUM_CS_STPER];
-	unsigned total_bw;
-
-	dma_addr_t irq_phys;
-	struct he_irq *irq_base, *irq_head, *irq_tail;
-	volatile unsigned *irq_tailoffset;
-	int irq_peak;
-
-	struct tasklet_struct tasklet;
-	struct dma_pool *tpd_pool;
-	struct list_head outstanding_tpds;
-
-	dma_addr_t tpdrq_phys;
-	struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head;
-
-	spinlock_t global_lock;		/* 8.1.5 pci transaction ordering
-					  error problem */
-	dma_addr_t rbrq_phys;
-	struct he_rbrq *rbrq_base, *rbrq_head;
-	int rbrq_peak;
-
-	struct he_buff **rbpl_virt;
-	unsigned long *rbpl_table;
-	unsigned long rbpl_hint;
-	struct dma_pool *rbpl_pool;
-	dma_addr_t rbpl_phys;
-	struct he_rbp *rbpl_base, *rbpl_tail;
-	struct list_head rbpl_outstanding;
-	int rbpl_peak;
-
-	dma_addr_t tbrq_phys;
-	struct he_tbrq *tbrq_base, *tbrq_head;
-	int tbrq_peak;
-
-	dma_addr_t hsp_phys;
-	struct he_hsp *hsp;
-
-	struct pci_dev *pci_dev;
-	struct atm_dev *atm_dev;
-	struct he_dev *next;
-};
-
-#define HE_MAXIOV 20
-
-struct he_vcc
-{
-	struct list_head buffers;
-	int pdu_len;
-	int rc_index;
-
-	wait_queue_head_t rx_waitq;
-	wait_queue_head_t tx_waitq;
-};
-
-#define HE_VCC(vcc)	((struct he_vcc *)(vcc->dev_data))
-
-#define PCI_VENDOR_ID_FORE	0x1127
-#define PCI_DEVICE_ID_FORE_HE	0x400
-
-#define GEN_CNTL_0				0x40
-#define  INT_PROC_ENBL		(1<<25)
-#define  SLAVE_ENDIAN_MODE	(1<<16)
-#define  MRL_ENB		(1<<5)
-#define  MRM_ENB		(1<<4)
-#define  INIT_ENB		(1<<2)
-#define  IGNORE_TIMEOUT		(1<<1)
-#define  ENBL_64		(1<<0)
-
-#define MIN_PCI_LATENCY		32	/* errata 8.1.3 */
-
-#define HE_DEV(dev) ((struct he_dev *) (dev)->dev_data)
-
-#define he_is622(dev)	((dev)->media & 0x1)
-#define he_isMM(dev)	((dev)->media & 0x20)
-
-#define HE_REGMAP_SIZE	0x100000
-
-#define RESET_CNTL	0x80000
-#define  BOARD_RST_STATUS	(1<<6)
-
-#define HOST_CNTL	0x80004
-#define  PCI_BUS_SIZE64			(1<<27)
-#define  DESC_RD_STATIC_64		(1<<26)
-#define  DATA_RD_STATIC_64		(1<<25)
-#define  DATA_WR_STATIC_64		(1<<24)
-#define  ID_CS				(1<<12)
-#define  ID_WREN			(1<<11)
-#define  ID_DOUT			(1<<10)
-#define   ID_DOFFSET			10
-#define  ID_DIN				(1<<9)
-#define  ID_CLOCK			(1<<8)
-#define  QUICK_RD_RETRY			(1<<7)
-#define  QUICK_WR_RETRY			(1<<6)
-#define  OUTFF_ENB			(1<<5)
-#define  CMDFF_ENB			(1<<4)
-#define  PERR_INT_ENB			(1<<2)
-#define  IGNORE_INTR			(1<<0)
-
-#define LB_SWAP		0x80008
-#define  SWAP_RNUM_MAX(x)	(x<<27)
-#define  DATA_WR_SWAP		(1<<20)
-#define  DESC_RD_SWAP		(1<<19)
-#define  DATA_RD_SWAP		(1<<18)
-#define  INTR_SWAP		(1<<17)
-#define  DESC_WR_SWAP		(1<<16)
-#define  SDRAM_INIT		(1<<15)
-#define  BIG_ENDIAN_HOST	(1<<14)
-#define  XFER_SIZE		(1<<7)
-
-#define LB_MEM_ADDR	0x8000c
-#define LB_MEM_DATA	0x80010
-
-#define LB_MEM_ACCESS	0x80014
-#define  LB_MEM_HNDSHK		(1<<30)
-#define  LM_MEM_WRITE		(0x7)
-#define  LM_MEM_READ		(0x3)
-
-#define SDRAM_CTL	0x80018
-#define  LB_64_ENB		(1<<3)
-#define  LB_TWR			(1<<2)
-#define  LB_TRP			(1<<1)
-#define  LB_TRAS		(1<<0)
-
-#define INT_FIFO	0x8001c
-#define  INT_MASK_D		(1<<15)
-#define  INT_MASK_C		(1<<14)
-#define  INT_MASK_B		(1<<13)
-#define  INT_MASK_A		(1<<12)
-#define  INT_CLEAR_D		(1<<11)
-#define  INT_CLEAR_C		(1<<10)
-#define  INT_CLEAR_B		(1<<9)
-#define  INT_CLEAR_A		(1<<8)
-
-#define ABORT_ADDR	0x80020
-
-#define IRQ0_BASE	0x80080
-#define  IRQ_BASE(x)		(x<<12)
-#define  IRQ_MASK		((CONFIG_IRQ_SIZE<<2)-1)	/* was 0x3ff */
-#define  IRQ_TAIL(x)		(((unsigned long)(x)) & IRQ_MASK)
-#define IRQ0_HEAD	0x80084
-#define  IRQ_SIZE(x)		(x<<22)
-#define  IRQ_THRESH(x)		(x<<12)
-#define  IRQ_HEAD(x)		(x<<2)
-/* #define  IRQ_PENDING		(1) 		conflict with linux/irq.h */
-#define IRQ0_CNTL	0x80088
-#define  IRQ_ADDRSEL(x)		(x<<2)
-#define  IRQ_INT_A		(0<<2)
-#define  IRQ_INT_B		(1<<2)
-#define  IRQ_INT_C		(2<<2)
-#define  IRQ_INT_D		(3<<2)
-#define  IRQ_TYPE_ADDR		0x1
-#define  IRQ_TYPE_LINE		0x0
-#define IRQ0_DATA	0x8008c
-
-#define IRQ1_BASE	0x80090
-#define IRQ1_HEAD	0x80094
-#define IRQ1_CNTL	0x80098
-#define IRQ1_DATA	0x8009c
-
-#define IRQ2_BASE	0x800a0
-#define IRQ2_HEAD	0x800a4
-#define IRQ2_CNTL	0x800a8
-#define IRQ2_DATA	0x800ac
-
-#define IRQ3_BASE	0x800b0
-#define IRQ3_HEAD	0x800b4
-#define IRQ3_CNTL	0x800b8
-#define IRQ3_DATA	0x800bc
-
-#define GRP_10_MAP	0x800c0
-#define GRP_32_MAP	0x800c4
-#define GRP_54_MAP	0x800c8
-#define GRP_76_MAP	0x800cc
-
-#define	G0_RBPS_S	0x80400
-#define G0_RBPS_T	0x80404
-#define  RBP_TAIL(x)		((x)<<3)
-#define  RBP_MASK(x)		((x)|0x1fff)
-#define G0_RBPS_QI	0x80408
-#define  RBP_QSIZE(x)		((x)<<14)
-#define  RBP_INT_ENB		(1<<13)
-#define  RBP_THRESH(x)		(x)
-#define G0_RBPS_BS	0x8040c
-#define G0_RBPL_S	0x80410
-#define G0_RBPL_T	0x80414
-#define G0_RBPL_QI	0x80418 
-#define G0_RBPL_BS	0x8041c
-
-#define	G1_RBPS_S	0x80420
-#define G1_RBPS_T	0x80424
-#define G1_RBPS_QI	0x80428
-#define G1_RBPS_BS	0x8042c
-#define G1_RBPL_S	0x80430
-#define G1_RBPL_T	0x80434
-#define G1_RBPL_QI	0x80438
-#define G1_RBPL_BS	0x8043c
-
-#define	G2_RBPS_S	0x80440
-#define G2_RBPS_T	0x80444
-#define G2_RBPS_QI	0x80448
-#define G2_RBPS_BS	0x8044c
-#define G2_RBPL_S	0x80450
-#define G2_RBPL_T	0x80454
-#define G2_RBPL_QI	0x80458
-#define G2_RBPL_BS	0x8045c
-
-#define	G3_RBPS_S	0x80460
-#define G3_RBPS_T	0x80464
-#define G3_RBPS_QI	0x80468
-#define G3_RBPS_BS	0x8046c
-#define G3_RBPL_S	0x80470
-#define G3_RBPL_T	0x80474
-#define G3_RBPL_QI	0x80478
-#define G3_RBPL_BS	0x8047c
-
-#define	G4_RBPS_S	0x80480
-#define G4_RBPS_T	0x80484
-#define G4_RBPS_QI	0x80488
-#define G4_RBPS_BS	0x8048c
-#define G4_RBPL_S	0x80490
-#define G4_RBPL_T	0x80494
-#define G4_RBPL_QI	0x80498
-#define G4_RBPL_BS	0x8049c
-
-#define	G5_RBPS_S	0x804a0
-#define G5_RBPS_T	0x804a4
-#define G5_RBPS_QI	0x804a8
-#define G5_RBPS_BS	0x804ac
-#define G5_RBPL_S	0x804b0
-#define G5_RBPL_T	0x804b4
-#define G5_RBPL_QI	0x804b8
-#define G5_RBPL_BS	0x804bc
-
-#define	G6_RBPS_S	0x804c0
-#define G6_RBPS_T	0x804c4
-#define G6_RBPS_QI	0x804c8
-#define G6_RBPS_BS	0x804cc
-#define G6_RBPL_S	0x804d0
-#define G6_RBPL_T	0x804d4
-#define G6_RBPL_QI	0x804d8
-#define G6_RBPL_BS	0x804dc
-
-#define	G7_RBPS_S	0x804e0
-#define G7_RBPS_T	0x804e4
-#define G7_RBPS_QI	0x804e8
-#define G7_RBPS_BS	0x804ec
-
-#define G7_RBPL_S	0x804f0
-#define G7_RBPL_T	0x804f4
-#define G7_RBPL_QI	0x804f8
-#define G7_RBPL_BS	0x804fc
-
-#define G0_RBRQ_ST	0x80500
-#define G0_RBRQ_H	0x80504
-#define G0_RBRQ_Q	0x80508
-#define  RBRQ_THRESH(x)		((x)<<13)
-#define  RBRQ_SIZE(x)		(x)
-#define G0_RBRQ_I	0x8050c
-#define  RBRQ_TIME(x)		((x)<<8)
-#define  RBRQ_COUNT(x)		(x)
-
-/* fill in 1 ... 7 later */
-
-#define G0_TBRQ_B_T	0x80600
-#define G0_TBRQ_H	0x80604
-#define G0_TBRQ_S	0x80608
-#define G0_TBRQ_THRESH	0x8060c
-#define  TBRQ_THRESH(x)		(x)
-
-/* fill in 1 ... 7 later */
-
-#define RH_CONFIG	0x805c0
-#define  PHY_INT_ENB	(1<<10)
-#define  OAM_GID(x)	(x<<7)
-#define  PTMR_PRE(x)	(x)
-
-#define G0_INMQ_S	0x80580
-#define G0_INMQ_L	0x80584
-#define G1_INMQ_S	0x80588
-#define G1_INMQ_L	0x8058c
-#define G2_INMQ_S	0x80590
-#define G2_INMQ_L	0x80594
-#define G3_INMQ_S	0x80598
-#define G3_INMQ_L	0x8059c
-#define G4_INMQ_S	0x805a0
-#define G4_INMQ_L	0x805a4
-#define G5_INMQ_S	0x805a8
-#define G5_INMQ_L	0x805ac
-#define G6_INMQ_S	0x805b0
-#define G6_INMQ_L	0x805b4
-#define G7_INMQ_S	0x805b8
-#define G7_INMQ_L	0x805bc
-
-#define TPDRQ_B_H	0x80680
-#define TPDRQ_T		0x80684
-#define TPDRQ_S		0x80688
-
-#define UBUFF_BA	0x8068c
-
-#define RLBF0_H		0x806c0
-#define RLBF0_T		0x806c4
-#define RLBF1_H		0x806c8
-#define RLBF1_T		0x806cc
-#define RLBC_H		0x806d0
-#define RLBC_T		0x806d4
-#define RLBC_H2		0x806d8
-#define TLBF_H		0x806e0
-#define TLBF_T		0x806e4
-#define RLBF0_C		0x806e8
-#define RLBF1_C		0x806ec
-#define RXTHRSH		0x806f0
-#define LITHRSH		0x806f4
-
-#define LBARB		0x80700
-#define  SLICE_X(x)		 (x<<28)
-#define  ARB_RNUM_MAX(x)	 (x<<23)
-#define  TH_PRTY(x)		 (x<<21)
-#define  RH_PRTY(x)		 (x<<19)
-#define  TL_PRTY(x)		 (x<<17)
-#define  RL_PRTY(x)		 (x<<15)
-#define  BUS_MULTI(x)		 (x<<8)
-#define  NET_PREF(x)		 (x)
-
-#define SDRAMCON	0x80704
-#define	 BANK_ON		(1<<14)
-#define	 WIDE_DATA		(1<<13)
-#define	 TWR_WAIT		(1<<12)
-#define	 TRP_WAIT		(1<<11)
-#define	 TRAS_WAIT		(1<<10)
-#define	 REF_RATE(x)		(x)
-
-#define LBSTAT		0x80708
-
-#define RCC_STAT	0x8070c
-#define  RCC_BUSY		(1)
-
-#define TCMCONFIG	0x80740
-#define  TM_DESL2		(1<<10)
-#define	 TM_BANK_WAIT(x)	(x<<6)
-#define	 TM_ADD_BANK4(x)	(x<<4)
-#define  TM_PAR_CHECK(x)	(x<<3)
-#define  TM_RW_WAIT(x)		(x<<2)
-#define  TM_SRAM_TYPE(x)	(x)
-
-#define TSRB_BA		0x80744	
-#define TSRC_BA		0x80748	
-#define TMABR_BA	0x8074c	
-#define TPD_BA		0x80750	
-#define TSRD_BA		0x80758	
-
-#define TX_CONFIG	0x80760
-#define  DRF_THRESH(x)		(x<<22)
-#define  TX_UT_MODE(x)		(x<<21)
-#define  TX_VCI_MASK(x)		(x<<17)
-#define  LBFREE_CNT(x)		(x)
-
-#define TXAAL5_PROTO	0x80764
-#define  CPCS_UU(x)		(x<<8)
-#define  CPI(x)			(x)
-
-#define RCMCONFIG	0x80780
-#define  RM_DESL2(x)		(x<<10)
-#define  RM_BANK_WAIT(x)	(x<<6)
-#define  RM_ADD_BANK(x)		(x<<4)
-#define  RM_PAR_CHECK(x)	(x<<3)
-#define  RM_RW_WAIT(x)		(x<<2)
-#define  RM_SRAM_TYPE(x)	(x)
-
-#define RCMRSRB_BA	0x80784
-#define RCMLBM_BA	0x80788
-#define RCMABR_BA	0x8078c
-
-#define RC_CONFIG	0x807c0
-#define  UT_RD_DELAY(x)		(x<<11)
-#define  WRAP_MODE(x)		(x<<10)
-#define  RC_UT_MODE(x)		(x<<9)
-#define  RX_ENABLE		(1<<8)
-#define  RX_VALVP(x)		(x<<4)
-#define  RX_VALVC(x)		(x)
-
-#define MCC		0x807c4
-#define OEC		0x807c8
-#define DCC		0x807cc
-#define CEC		0x807d0
-
-#define HSP_BA		0x807f0
-
-#define LB_CONFIG	0x807f4
-#define  LB_SIZE(x)		(x)
-
-#define CON_DAT		0x807f8
-#define CON_CTL		0x807fc
-#define  CON_CTL_MBOX		(2<<30)
-#define  CON_CTL_TCM		(1<<30)
-#define  CON_CTL_RCM		(0<<30)
-#define  CON_CTL_WRITE		(1<<29)
-#define  CON_CTL_READ		(0<<29)
-#define  CON_CTL_BUSY		(1<<28)
-#define  CON_BYTE_DISABLE_3	(1<<22)		/* 24..31 */
-#define  CON_BYTE_DISABLE_2	(1<<21)		/* 16..23 */
-#define  CON_BYTE_DISABLE_1	(1<<20)		/* 8..15 */
-#define  CON_BYTE_DISABLE_0	(1<<19)		/* 0..7 */
-#define  CON_CTL_ADDR(x)	(x)
-
-#define FRAMER		0x80800		/* to 0x80bfc */
-
-/* 3.3 network controller (internal) mailbox registers */
-
-#define CS_STPER0	0x0
-	/* ... */
-#define CS_STPER31	0x01f
-
-#define CS_STTIM0	0x020
-	/* ... */
-#define CS_STTIM31	0x03f
-
-#define CS_TGRLD0	0x040
-	/* ... */
-#define CS_TGRLD15	0x04f
-
-#define CS_ERTHR0	0x050
-#define CS_ERTHR1	0x051
-#define CS_ERTHR2	0x052
-#define CS_ERTHR3	0x053
-#define CS_ERTHR4	0x054
-#define CS_ERCTL0	0x055
-#define  TX_ENABLE		(1<<28)
-#define  ER_ENABLE		(1<<27)
-#define CS_ERCTL1	0x056
-#define CS_ERCTL2	0x057
-#define CS_ERSTAT0	0x058
-#define CS_ERSTAT1	0x059
-
-#define CS_RTCCT	0x060
-#define CS_RTFWC	0x061
-#define CS_RTFWR	0x062
-#define CS_RTFTC	0x063
-#define CS_RTATR	0x064
-
-#define CS_TFBSET	0x070
-#define CS_TFBADD	0x071
-#define CS_TFBSUB	0x072
-#define CS_WCRMAX	0x073
-#define CS_WCRMIN	0x074
-#define CS_WCRINC	0x075
-#define CS_WCRDEC	0x076
-#define CS_WCRCEIL	0x077
-#define CS_BWDCNT	0x078
-
-#define CS_OTPPER	0x080
-#define CS_OTWPER	0x081
-#define CS_OTTLIM	0x082
-#define CS_OTTCNT	0x083
-
-#define CS_HGRRT0	0x090
-	/* ... */
-#define CS_HGRRT7	0x097
-
-#define CS_ORPTRS	0x0a0
-
-#define RXCON_CLOSE	0x100
-
-
-#define RCM_MEM_SIZE	0x10000		/* 1M of 32-bit registers */
-#define TCM_MEM_SIZE	0x20000		/* 2M of 32-bit registers */
-
-/* 2.5 transmit connection memory registers */
-
-#define TSR0_CONN_STATE(x)	((x>>28) & 0x7)
-#define TSR0_USE_WMIN		(1<<23)
-#define TSR0_GROUP(x)		((x & 0x7)<<18)
-#define TSR0_ABR		(2<<16)
-#define TSR0_UBR		(1<<16)
-#define TSR0_CBR		(0<<16)
-#define TSR0_PROT		(1<<15)
-#define TSR0_AAL0_SDU		(2<<12)
-#define TSR0_AAL0		(1<<12)
-#define TSR0_AAL5		(0<<12)
-#define TSR0_HALT_ER		(1<<11)
-#define TSR0_MARK_CI		(1<<10)
-#define TSR0_MARK_ER		(1<<9)
-#define TSR0_UPDATE_GER		(1<<8)
-#define TSR0_RC_INDEX(x)	(x & 0x1F)
-
-#define TSR1_PCR(x)		((x & 0x7FFF)<<16)
-#define TSR1_MCR(x)		(x & 0x7FFF)
-
-#define TSR2_ACR(x)		((x & 0x7FFF)<<16)
-
-#define TSR3_NRM_CNT(x)		((x & 0xFF)<<24)
-#define TSR3_CRM_CNT(x)		(x & 0xFFFF)
-
-#define TSR4_FLUSH_CONN		(1<<31)
-#define TSR4_SESSION_ENDED	(1<<30)
-#define TSR4_CRC10		(1<<28)
-#define TSR4_NULL_CRC10		(1<<27)
-#define TSR4_PROT		(1<<26)
-#define TSR4_AAL0_SDU		(2<<23)
-#define TSR4_AAL0		(1<<23)
-#define TSR4_AAL5		(0<<23)
-
-#define TSR9_OPEN_CONN		(1<<20)
-
-#define TSR11_ICR(x)		((x & 0x7FFF)<<16)
-#define TSR11_TRM(x)		((x & 0x7)<<13)
-#define TSR11_NRM(x)		((x & 0x7)<<10)
-#define TSR11_ADTF(x)		(x & 0x3FF)
-
-#define TSR13_RDF(x)		((x & 0xF)<<23)
-#define TSR13_RIF(x)		((x & 0xF)<<19)
-#define TSR13_CDF(x)		((x & 0x7)<<16)
-#define TSR13_CRM(x)		(x & 0xFFFF)
-
-#define TSR14_DELETE		(1<<31)
-#define TSR14_ABR_CLOSE		(1<<16)
-
-/* 2.7.1 per connection receieve state registers */
-
-#define RSR0_START_PDU	(1<<10)
-#define RSR0_OPEN_CONN	(1<<6)
-#define RSR0_CLOSE_CONN	(0<<6)
-#define RSR0_PPD_ENABLE	(1<<5)
-#define RSR0_EPD_ENABLE	(1<<4)
-#define RSR0_TCP_CKSUM	(1<<3)
-#define RSR0_AAL5		(0)
-#define RSR0_AAL0		(1)
-#define RSR0_AAL0_SDU		(2)
-#define RSR0_RAWCELL		(3)
-#define RSR0_RAWCELL_CRC10	(4)
-
-#define RSR1_AQI_ENABLE	(1<<20)
-#define RSR1_RBPL_ONLY	(1<<19)
-#define RSR1_GROUP(x)	((x)<<16)
-
-#define RSR4_AQI_ENABLE (1<<30)
-#define RSR4_GROUP(x)	((x)<<27)
-#define RSR4_RBPL_ONLY	(1<<26)
-
-/* 2.1.4 transmit packet descriptor */
-
-#define	TPD_USERCELL		0x0
-#define	TPD_SEGMENT_OAMF5	0x4
-#define	TPD_END2END_OAMF5	0x5
-#define	TPD_RMCELL		0x6
-#define TPD_CELLTYPE(x)		(x<<3)
-#define TPD_EOS			(1<<2)
-#define TPD_CLP			(1<<1)
-#define TPD_INT			(1<<0)
-#define TPD_LST		(1<<31)
-
-/* table 4.3 serial eeprom information */
-
-#define PROD_ID		0x08	/* char[] */
-#define  PROD_ID_LEN	30
-#define HW_REV		0x26	/* char[] */
-#define M_SN		0x3a	/* integer */
-#define MEDIA		0x3e	/* integer */
-#define  HE155MM	0x26
-#define  HE622MM	0x27
-#define  HE155SM	0x46
-#define  HE622SM	0x47
-#define MAC_ADDR	0x42	/* char[] */
-
-#define CS_LOW		0x0
-#define CS_HIGH		ID_CS /* HOST_CNTL_ID_PROM_SEL */
-#define CLK_LOW		0x0
-#define CLK_HIGH	ID_CLOCK /* HOST_CNTL_ID_PROM_CLOCK */
-#define SI_HIGH		ID_DIN /* HOST_CNTL_ID_PROM_DATA_IN */
-#define EEPROM_DELAY	400 /* microseconds */
-
-#endif /* _HE_H_ */
diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c
deleted file mode 100644
index 4bbcca7..0000000
--- a/drivers/atm/idt77105.c
+++ /dev/null
@@ -1,376 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* drivers/atm/idt77105.c - IDT77105 (PHY) driver */
- 
-/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.c */
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/atm_idt77105.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <asm/param.h>
-#include <linux/uaccess.h>
-
-#include "idt77105.h"
-
-#undef GENERAL_DEBUG
-
-#ifdef GENERAL_DEBUG
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-
-struct idt77105_priv {
-	struct idt77105_stats stats;    /* link diagnostics */
-	struct atm_dev *dev;		/* device back-pointer */
-	struct idt77105_priv *next;
-        int loop_mode;
-        unsigned char old_mcr;          /* storage of MCR reg while signal lost */
-};
-
-static DEFINE_SPINLOCK(idt77105_priv_lock);
-
-#define PRIV(dev) ((struct idt77105_priv *) dev->phy_data)
-
-#define PUT(val,reg) dev->ops->phy_put(dev,val,IDT77105_##reg)
-#define GET(reg) dev->ops->phy_get(dev,IDT77105_##reg)
-
-static void idt77105_stats_timer_func(struct timer_list *);
-static void idt77105_restart_timer_func(struct timer_list *);
-
-
-static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func);
-static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func);
-static int start_timer = 1;
-static struct idt77105_priv *idt77105_all = NULL;
-
-/*
- * Retrieve the value of one of the IDT77105's counters.
- * `counter' is one of the IDT77105_CTRSEL_* constants.
- */
-static u16 get_counter(struct atm_dev *dev, int counter)
-{
-        u16 val;
-        
-        /* write the counter bit into PHY register 6 */
-        PUT(counter, CTRSEL);
-        /* read the low 8 bits from register 4 */
-        val = GET(CTRLO);
-        /* read the high 8 bits from register 5 */
-        val |= GET(CTRHI)<<8;
-        
-        return val;
-}
-
-/*
- * Timer function called every second to gather statistics
- * from the 77105. This is done because the h/w registers
- * will overflow if not read at least once per second. The
- * kernel's stats are much higher precision. Also, having
- * a separate copy of the stats allows implementation of
- * an ioctl which gathers the stats *without* zero'ing them.
- */
-static void idt77105_stats_timer_func(struct timer_list *unused)
-{
-	struct idt77105_priv *walk;
-	struct atm_dev *dev;
-	struct idt77105_stats *stats;
-
-        DPRINTK("IDT77105 gathering statistics\n");
-	for (walk = idt77105_all; walk; walk = walk->next) {
-		dev = walk->dev;
-                
-		stats = &walk->stats;
-                stats->symbol_errors += get_counter(dev, IDT77105_CTRSEL_SEC);
-                stats->tx_cells += get_counter(dev, IDT77105_CTRSEL_TCC);
-                stats->rx_cells += get_counter(dev, IDT77105_CTRSEL_RCC);
-                stats->rx_hec_errors += get_counter(dev, IDT77105_CTRSEL_RHEC);
-	}
-        if (!start_timer) mod_timer(&stats_timer,jiffies+IDT77105_STATS_TIMER_PERIOD);
-}
-
-
-/*
- * A separate timer func which handles restarting PHY chips which
- * have had the cable re-inserted after being pulled out. This is
- * done by polling the Good Signal Bit in the Interrupt Status
- * register every 5 seconds. The other technique (checking Good
- * Signal Bit in the interrupt handler) cannot be used because PHY
- * interrupts need to be disabled when the cable is pulled out
- * to avoid lots of spurious cell error interrupts.
- */
-static void idt77105_restart_timer_func(struct timer_list *unused)
-{
-	struct idt77105_priv *walk;
-	struct atm_dev *dev;
-        unsigned char istat;
-
-        DPRINTK("IDT77105 checking for cable re-insertion\n");
-	for (walk = idt77105_all; walk; walk = walk->next) {
-		dev = walk->dev;
-                
-                if (dev->signal != ATM_PHY_SIG_LOST)
-                    continue;
-                    
-                istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
-                if (istat & IDT77105_ISTAT_GOODSIG) {
-                    /* Found signal again */
-                    atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
-	            printk(KERN_NOTICE "%s(itf %d): signal detected again\n",
-                        dev->type,dev->number);
-                    /* flush the receive FIFO */
-                    PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
-                    /* re-enable interrupts */
-	            PUT( walk->old_mcr ,MCR);
-                }
-	}
-        if (!start_timer) mod_timer(&restart_timer,jiffies+IDT77105_RESTART_TIMER_PERIOD);
-}
-
-
-static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int zero)
-{
-	unsigned long flags;
-	struct idt77105_stats stats;
-
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	memcpy(&stats, &PRIV(dev)->stats, sizeof(struct idt77105_stats));
-	if (zero)
-		memset(&PRIV(dev)->stats, 0, sizeof(struct idt77105_stats));
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	if (arg == NULL)
-		return 0;
-	return copy_to_user(arg, &stats,
-		    sizeof(struct idt77105_stats)) ? -EFAULT : 0;
-}
-
-
-static int set_loopback(struct atm_dev *dev,int mode)
-{
-	int diag;
-
-	diag = GET(DIAG) & ~IDT77105_DIAG_LCMASK;
-	switch (mode) {
-		case ATM_LM_NONE:
-			break;
-		case ATM_LM_LOC_ATM:
-			diag |= IDT77105_DIAG_LC_PHY_LOOPBACK;
-			break;
-		case ATM_LM_RMT_ATM:
-			diag |= IDT77105_DIAG_LC_LINE_LOOPBACK;
-			break;
-		default:
-			return -EINVAL;
-	}
-	PUT(diag,DIAG);
-	printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", dev->type,
-	    dev->number,
-	    (mode == ATM_LM_NONE ? "NONE" : 
-	      (mode == ATM_LM_LOC_ATM ? "DIAG (local)" :
-		(mode == IDT77105_DIAG_LC_LINE_LOOPBACK ? "LOOP (remote)" :
-		  "unknown")))
-		    );
-	PRIV(dev)->loop_mode = mode;
-	return 0;
-}
-
-
-static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-        printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number);
-	switch (cmd) {
-		case IDT77105_GETSTATZ:
-			if (!capable(CAP_NET_ADMIN)) return -EPERM;
-			fallthrough;
-		case IDT77105_GETSTAT:
-			return fetch_stats(dev, arg, cmd == IDT77105_GETSTATZ);
-		case ATM_SETLOOP:
-			return set_loopback(dev,(int)(unsigned long) arg);
-		case ATM_GETLOOP:
-			return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-			    -EFAULT : 0;
-		case ATM_QUERYLOOP:
-			return put_user(ATM_LM_LOC_ATM | ATM_LM_RMT_ATM,
-			    (int __user *) arg) ? -EFAULT : 0;
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-
-
-static void idt77105_int(struct atm_dev *dev)
-{
-        unsigned char istat;
-        
-        istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
-     
-        DPRINTK("IDT77105 generated an interrupt, istat=%02x\n", (unsigned)istat);
-                
-        if (istat & IDT77105_ISTAT_RSCC) {
-            /* Rx Signal Condition Change - line went up or down */
-            if (istat & IDT77105_ISTAT_GOODSIG) {   /* signal detected again */
-                /* This should not happen (restart timer does it) but JIC */
-		atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
-            } else {    /* signal lost */
-                /*
-                 * Disable interrupts and stop all transmission and
-                 * reception - the restart timer will restore these.
-                 */
-                PRIV(dev)->old_mcr = GET(MCR);
-	        PUT(
-                    (PRIV(dev)->old_mcr|
-                    IDT77105_MCR_DREC|
-                    IDT77105_MCR_DRIC|
-                    IDT77105_MCR_HALTTX
-                    ) & ~IDT77105_MCR_EIP, MCR);
-		atm_dev_signal_change(dev, ATM_PHY_SIG_LOST);
-	        printk(KERN_NOTICE "%s(itf %d): signal lost\n",
-                    dev->type,dev->number);
-            }
-        }
-        
-        if (istat & IDT77105_ISTAT_RFO) {
-            /* Rx FIFO Overrun -- perform a FIFO flush */
-            PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
-	    printk(KERN_NOTICE "%s(itf %d): receive FIFO overrun\n",
-                dev->type,dev->number);
-        }
-#ifdef GENERAL_DEBUG
-        if (istat & (IDT77105_ISTAT_HECERR | IDT77105_ISTAT_SCR |
-                     IDT77105_ISTAT_RSE)) {
-            /* normally don't care - just report in stats */
-	    printk(KERN_NOTICE "%s(itf %d): received cell with error\n",
-                dev->type,dev->number);
-        }
-#endif
-}
-
-
-static int idt77105_start(struct atm_dev *dev)
-{
-	unsigned long flags;
-
-	if (!(dev->phy_data = kmalloc_obj(struct idt77105_priv)))
-		return -ENOMEM;
-	PRIV(dev)->dev = dev;
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	PRIV(dev)->next = idt77105_all;
-	idt77105_all = PRIV(dev);
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats));
-        
-        /* initialise dev->signal from Good Signal Bit */
-	atm_dev_signal_change(dev,
-		GET(ISTAT) & IDT77105_ISTAT_GOODSIG ?
-		ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST);
-	if (dev->signal == ATM_PHY_SIG_LOST)
-		printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
-		    dev->number);
-
-        /* initialise loop mode from hardware */
-        switch ( GET(DIAG) & IDT77105_DIAG_LCMASK ) {
-        case IDT77105_DIAG_LC_NORMAL:
-            PRIV(dev)->loop_mode = ATM_LM_NONE;
-            break;
-        case IDT77105_DIAG_LC_PHY_LOOPBACK:
-            PRIV(dev)->loop_mode = ATM_LM_LOC_ATM;
-            break;
-        case IDT77105_DIAG_LC_LINE_LOOPBACK:
-            PRIV(dev)->loop_mode = ATM_LM_RMT_ATM;
-            break;
-        }
-        
-        /* enable interrupts, e.g. on loss of signal */
-        PRIV(dev)->old_mcr = GET(MCR);
-        if (dev->signal == ATM_PHY_SIG_FOUND) {
-            PRIV(dev)->old_mcr |= IDT77105_MCR_EIP;
-	    PUT(PRIV(dev)->old_mcr, MCR);
-        }
-
-                    
-	idt77105_stats_timer_func(0); /* clear 77105 counters */
-	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
-        
-	spin_lock_irqsave(&idt77105_priv_lock, flags);
-	if (start_timer) {
-		start_timer = 0;
-                
-		stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD;
-		add_timer(&stats_timer);
-                
-		restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD;
-		add_timer(&restart_timer);
-	}
-	spin_unlock_irqrestore(&idt77105_priv_lock, flags);
-	return 0;
-}
-
-
-static int idt77105_stop(struct atm_dev *dev)
-{
-	struct idt77105_priv *walk, *prev;
-
-        DPRINTK("%s(itf %d): stopping IDT77105\n",dev->type,dev->number);
-        
-        /* disable interrupts */
-	PUT( GET(MCR) & ~IDT77105_MCR_EIP, MCR );
-        
-        /* detach private struct from atm_dev & free */
-	for (prev = NULL, walk = idt77105_all ;
-             walk != NULL;
-             prev = walk, walk = walk->next) {
-            if (walk->dev == dev) {
-                if (prev != NULL)
-                    prev->next = walk->next;
-                else
-                    idt77105_all = walk->next;
-	        dev->phy = NULL;
-                dev->phy_data = NULL;
-                kfree(walk);
-                break;
-            }
-        }
-
-	return 0;
-}
-
-
-static const struct atmphy_ops idt77105_ops = {
-	.start = 	idt77105_start,
-	.ioctl =	idt77105_ioctl,
-	.interrupt =	idt77105_int,
-	.stop =		idt77105_stop,
-};
-
-
-int idt77105_init(struct atm_dev *dev)
-{
-	dev->phy = &idt77105_ops;
-	return 0;
-}
-
-EXPORT_SYMBOL(idt77105_init);
-
-static void __exit idt77105_exit(void)
-{
-	/* turn off timers */
-	timer_delete_sync(&stats_timer);
-	timer_delete_sync(&restart_timer);
-}
-
-module_exit(idt77105_exit);
-
-MODULE_DESCRIPTION("IDT77105 PHY driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/idt77105.h b/drivers/atm/idt77105.h
deleted file mode 100644
index 8dfea9e..0000000
--- a/drivers/atm/idt77105.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/idt77105.h - IDT77105 (PHY) declarations */
- 
-/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.h */
- 
-
-#ifndef DRIVER_ATM_IDT77105_H
-#define DRIVER_ATM_IDT77105_H
-
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-
-
-/* IDT77105 registers */
-
-#define IDT77105_MCR		0x0	/* Master Control Register */
-#define IDT77105_ISTAT	        0x1	/* Interrupt Status */
-#define IDT77105_DIAG   	0x2	/* Diagnostic Control */
-#define IDT77105_LEDHEC		0x3	/* LED Driver & HEC Status/Control */
-#define IDT77105_CTRLO		0x4	/* Low Byte Counter Register */
-#define IDT77105_CTRHI		0x5	/* High Byte Counter Register */
-#define IDT77105_CTRSEL		0x6	/* Counter Register Read Select */
-
-/* IDT77105 register values */
-
-/* MCR */
-#define IDT77105_MCR_UPLO	0x80	/* R/W, User Prog'le Output Latch */
-#define IDT77105_MCR_DREC	0x40	/* R/W, Discard Receive Error Cells */
-#define IDT77105_MCR_ECEIO	0x20	/* R/W, Enable Cell Error Interrupts
-                                         * Only */
-#define IDT77105_MCR_TDPC	0x10	/* R/W, Transmit Data Parity Check */
-#define IDT77105_MCR_DRIC	0x08	/* R/W, Discard Received Idle Cells */
-#define IDT77105_MCR_HALTTX	0x04	/* R/W, Halt Tx */
-#define IDT77105_MCR_UMODE	0x02	/* R/W, Utopia (cell/byte) Mode */
-#define IDT77105_MCR_EIP	0x01	/* R/W, Enable Interrupt Pin */
-
-/* ISTAT */
-#define IDT77105_ISTAT_GOODSIG	0x40	/* R, Good Signal Bit */
-#define IDT77105_ISTAT_HECERR	0x20	/* sticky, HEC Error*/
-#define IDT77105_ISTAT_SCR	0x10	/* sticky, Short Cell Received */
-#define IDT77105_ISTAT_TPE	0x08	/* sticky, Transmit Parity Error */
-#define IDT77105_ISTAT_RSCC	0x04	/* sticky, Rx Signal Condition Change */
-#define IDT77105_ISTAT_RSE	0x02	/* sticky, Rx Symbol Error */
-#define IDT77105_ISTAT_RFO	0x01	/* sticky, Rx FIFO Overrun */
-
-/* DIAG */
-#define IDT77105_DIAG_FTD	0x80	/* R/W, Force TxClav deassert */
-#define IDT77105_DIAG_ROS	0x40	/* R/W, RxClav operation select */
-#define IDT77105_DIAG_MPCS	0x20	/* R/W, Multi-PHY config'n select */
-#define IDT77105_DIAG_RFLUSH	0x10	/* R/W, clear receive FIFO */
-#define IDT77105_DIAG_ITPE	0x08	/* R/W, Insert Tx payload error */
-#define IDT77105_DIAG_ITHE	0x04	/* R/W, Insert Tx HEC error */
-#define IDT77105_DIAG_UMODE	0x02	/* R/W, Utopia (cell/byte) Mode */
-#define IDT77105_DIAG_LCMASK	0x03	/* R/W, Loopback Control */
-
-#define IDT77105_DIAG_LC_NORMAL         0x00	/* Receive from network */
-#define IDT77105_DIAG_LC_PHY_LOOPBACK	0x02
-#define IDT77105_DIAG_LC_LINE_LOOPBACK	0x03
-
-/* LEDHEC */
-#define IDT77105_LEDHEC_DRHC	0x40	/* R/W, Disable Rx HEC check */
-#define IDT77105_LEDHEC_DTHC	0x20	/* R/W, Disable Tx HEC calculation */
-#define IDT77105_LEDHEC_RPWMASK	0x18	/* R/W, RxRef pulse width select */
-#define IDT77105_LEDHEC_TFS	0x04	/* R, Tx FIFO Status (1=empty) */
-#define IDT77105_LEDHEC_TLS	0x02	/* R, Tx LED Status (1=lit) */
-#define IDT77105_LEDHEC_RLS	0x01	/* R, Rx LED Status (1=lit) */
-
-#define IDT77105_LEDHEC_RPW_1	0x00	/* RxRef active for 1 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_2	0x08	/* RxRef active for 2 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_4	0x10	/* RxRef active for 4 RxClk cycle */
-#define IDT77105_LEDHEC_RPW_8	0x18	/* RxRef active for 8 RxClk cycle */
-
-/* CTRSEL */
-#define IDT77105_CTRSEL_SEC	0x08	/* W, Symbol Error Counter */
-#define IDT77105_CTRSEL_TCC	0x04	/* W, Tx Cell Counter */
-#define IDT77105_CTRSEL_RCC	0x02	/* W, Rx Cell Counter */
-#define IDT77105_CTRSEL_RHEC	0x01	/* W, Rx HEC Error Counter */
-
-#ifdef __KERNEL__
-int idt77105_init(struct atm_dev *dev);
-#endif
-
-/*
- * Tunable parameters
- */
- 
-/* Time between samples of the hardware cell counters. Should be <= 1 sec */
-#define IDT77105_STATS_TIMER_PERIOD     (HZ) 
-/* Time between checks to see if the signal has been found again */
-#define IDT77105_RESTART_TIMER_PERIOD   (5 * HZ)
-
-#endif
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
deleted file mode 100644
index 7f8aaf5..0000000
--- a/drivers/atm/idt77252.c
+++ /dev/null
@@ -1,3797 +0,0 @@
-/******************************************************************* 
- *
- * Copyright (c) 2000 ATecoM GmbH 
- *
- * The author may be reached at ecd@atecom.com.
- *
- * 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *******************************************************************/
-
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/poison.h>
-#include <linux/skbuff.h>
-#include <linux/kernel.h>
-#include <linux/vmalloc.h>
-#include <linux/netdevice.h>
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/wait.h>
-#include <linux/jiffies.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-#include <asm/byteorder.h>
-
-#ifdef CONFIG_ATM_IDT77252_USE_SUNI
-#include "suni.h"
-#endif /* CONFIG_ATM_IDT77252_USE_SUNI */
-
-
-#include "idt77252.h"
-#include "idt77252_tables.h"
-
-static unsigned int vpibits = 1;
-
-
-#define ATM_IDT77252_SEND_IDLE 1
-
-
-/*
- * Debug HACKs.
- */
-#define DEBUG_MODULE 1
-#undef HAVE_EEPROM	/* does not work, yet. */
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-static unsigned long debug = DBG_GENERAL;
-#endif
-
-
-#define SAR_RX_DELAY	(SAR_CFG_RXINT_NODELAY)
-
-
-/*
- * SCQ Handling.
- */
-static struct scq_info *alloc_scq(struct idt77252_dev *, int);
-static void free_scq(struct idt77252_dev *, struct scq_info *);
-static int queue_skb(struct idt77252_dev *, struct vc_map *,
-		     struct sk_buff *, int oam);
-static void drain_scq(struct idt77252_dev *, struct vc_map *);
-static unsigned long get_free_scd(struct idt77252_dev *, struct vc_map *);
-static void fill_scd(struct idt77252_dev *, struct scq_info *, int);
-
-/*
- * FBQ Handling.
- */
-static int push_rx_skb(struct idt77252_dev *,
-		       struct sk_buff *, int queue);
-static void recycle_rx_skb(struct idt77252_dev *, struct sk_buff *);
-static void flush_rx_pool(struct idt77252_dev *, struct rx_pool *);
-static void recycle_rx_pool_skb(struct idt77252_dev *,
-				struct rx_pool *);
-static void add_rx_skb(struct idt77252_dev *, int queue,
-		       unsigned int size, unsigned int count);
-
-/*
- * RSQ Handling.
- */
-static int init_rsq(struct idt77252_dev *);
-static void deinit_rsq(struct idt77252_dev *);
-static void idt77252_rx(struct idt77252_dev *);
-
-/*
- * TSQ handling.
- */
-static int init_tsq(struct idt77252_dev *);
-static void deinit_tsq(struct idt77252_dev *);
-static void idt77252_tx(struct idt77252_dev *);
-
-
-/*
- * ATM Interface.
- */
-static void idt77252_dev_close(struct atm_dev *dev);
-static int idt77252_open(struct atm_vcc *vcc);
-static void idt77252_close(struct atm_vcc *vcc);
-static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int idt77252_send_oam(struct atm_vcc *vcc, void *cell,
-			     int flags);
-static void idt77252_phy_put(struct atm_dev *dev, unsigned char value,
-			     unsigned long addr);
-static unsigned char idt77252_phy_get(struct atm_dev *dev, unsigned long addr);
-static int idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos,
-			       int flags);
-static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos,
-			      char *page);
-static void idt77252_softint(struct work_struct *work);
-
-
-static const struct atmdev_ops idt77252_ops =
-{
-	.dev_close	= idt77252_dev_close,
-	.open		= idt77252_open,
-	.close		= idt77252_close,
-	.send		= idt77252_send,
-	.send_oam	= idt77252_send_oam,
-	.phy_put	= idt77252_phy_put,
-	.phy_get	= idt77252_phy_get,
-	.change_qos	= idt77252_change_qos,
-	.proc_read	= idt77252_proc_read,
-	.owner		= THIS_MODULE
-};
-
-static struct idt77252_dev *idt77252_chain = NULL;
-static unsigned int idt77252_sram_write_errors = 0;
-
-/*****************************************************************************/
-/*                                                                           */
-/* I/O and Utility Bus                                                       */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-waitfor_idle(struct idt77252_dev *card)
-{
-	u32 stat;
-
-	stat = readl(SAR_REG_STAT);
-	while (stat & SAR_STAT_CMDBZ)
-		stat = readl(SAR_REG_STAT);
-}
-
-static u32
-read_sram(struct idt77252_dev *card, unsigned long addr)
-{
-	unsigned long flags;
-	u32 value;
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_READ_SRAM | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	value = readl(SAR_REG_DR0);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-	return value;
-}
-
-static void
-write_sram(struct idt77252_dev *card, unsigned long addr, u32 value)
-{
-	unsigned long flags;
-
-	if ((idt77252_sram_write_errors == 0) &&
-	    (((addr > card->tst[0] + card->tst_size - 2) &&
-	      (addr < card->tst[0] + card->tst_size)) ||
-	     ((addr > card->tst[1] + card->tst_size - 2) &&
-	      (addr < card->tst[1] + card->tst_size)))) {
-		printk("%s: ERROR: TST JMP section at %08lx written: %08x\n",
-		       card->name, addr, value);
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(value, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-static u8
-read_utility(void *dev, unsigned long ubus_addr)
-{
-	struct idt77252_dev *card = dev;
-	unsigned long flags;
-	u8 value;
-
-	if (!card) {
-		printk("Error: No such device.\n");
-		return -1;
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_READ_UTILITY + ubus_addr, SAR_REG_CMD);
-	waitfor_idle(card);
-	value = readl(SAR_REG_DR0);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-	return value;
-}
-
-static void
-write_utility(void *dev, unsigned long ubus_addr, u8 value)
-{
-	struct idt77252_dev *card = dev;
-	unsigned long flags;
-
-	if (!card) {
-		printk("Error: No such device.\n");
-		return;
-	}
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel((u32) value, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_UTILITY + ubus_addr, SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-#ifdef HAVE_EEPROM
-static u32 rdsrtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO	/* 1 */
-};
-
-static u32 wrentab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK			/* 0 */
-};
-
-static u32 rdtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO	/* 1 */
-};
-
-static u32 wrtab[] =
-{
-	SAR_GP_EECS | SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	0,
-	SAR_GP_EESCLK,			/* 0 */
-	SAR_GP_EEDO,
-	SAR_GP_EESCLK | SAR_GP_EEDO,	/* 1 */
-	0,
-	SAR_GP_EESCLK			/* 0 */
-};
-
-static u32 clktab[] =
-{
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0,
-	SAR_GP_EESCLK,
-	0
-};
-
-static u32
-idt77252_read_gp(struct idt77252_dev *card)
-{
-	u32 gp;
-
-	gp = readl(SAR_REG_GP);
-#if 0
-	printk("RD: %s\n", gp & SAR_GP_EEDI ? "1" : "0");
-#endif
-	return gp;
-}
-
-static void
-idt77252_write_gp(struct idt77252_dev *card, u32 value)
-{
-	unsigned long flags;
-
-#if 0
-	printk("WR: %s %s %s\n", value & SAR_GP_EECS ? "   " : "/CS",
-	       value & SAR_GP_EESCLK ? "HIGH" : "LOW ",
-	       value & SAR_GP_EEDO   ? "1" : "0");
-#endif
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	waitfor_idle(card);
-	writel(value, SAR_REG_GP);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-}
-
-static u8
-idt77252_eeprom_read_status(struct idt77252_dev *card)
-{
-	u8 byte;
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
-		idt77252_write_gp(card, gp | rdsrtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	byte = 0;
-	for (i = 0, j = 0; i < 8; i++) {
-		byte <<= 1;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-
-		byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	return byte;
-}
-
-static u8
-idt77252_eeprom_read_byte(struct idt77252_dev *card, u8 offset)
-{
-	u8 byte;
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(rdtab); i++) {
-		idt77252_write_gp(card, gp | rdtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		offset >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	byte = 0;
-	for (i = 0, j = 0; i < 8; i++) {
-		byte <<= 1;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-
-		byte |= idt77252_read_gp(card) & SAR_GP_EEDI ? 1 : 0;
-
-		idt77252_write_gp(card, gp | clktab[j++]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	return byte;
-}
-
-static void
-idt77252_eeprom_write_byte(struct idt77252_dev *card, u8 offset, u8 data)
-{
-	u32 gp;
-	int i, j;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	for (i = 0; i < ARRAY_SIZE(wrentab); i++) {
-		idt77252_write_gp(card, gp | wrentab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0; i < ARRAY_SIZE(wrtab); i++) {
-		idt77252_write_gp(card, gp | wrtab[i]);
-		udelay(5);
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(offset & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		offset >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-
-	for (i = 0, j = 0; i < 8; i++) {
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(data & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		idt77252_write_gp(card, gp | clktab[j++] |
-					(data & 1 ? SAR_GP_EEDO : 0));
-		udelay(5);
-
-		data >>= 1;
-	}
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-}
-
-static void
-idt77252_eeprom_init(struct idt77252_dev *card)
-{
-	u32 gp;
-
-	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
-
-	idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS | SAR_GP_EESCLK);
-	udelay(5);
-	idt77252_write_gp(card, gp | SAR_GP_EECS);
-	udelay(5);
-}
-#endif /* HAVE_EEPROM */
-
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-static void
-dump_tct(struct idt77252_dev *card, int index)
-{
-	unsigned long tct;
-	int i;
-
-	tct = (unsigned long) (card->tct_base + index * SAR_SRAM_TCT_SIZE);
-
-	printk("%s: TCT %x:", card->name, index);
-	for (i = 0; i < 8; i++) {
-		printk(" %08x", read_sram(card, tct + i));
-	}
-	printk("\n");
-}
-
-static void
-idt77252_tx_dump(struct idt77252_dev *card)
-{
-	struct atm_vcc *vcc;
-	struct vc_map *vc;
-	int i;
-
-	printk("%s\n", __func__);
-	for (i = 0; i < card->tct_size; i++) {
-		vc = card->vcs[i];
-		if (!vc)
-			continue;
-
-		vcc = NULL;
-		if (vc->rx_vcc)
-			vcc = vc->rx_vcc;
-		else if (vc->tx_vcc)
-			vcc = vc->tx_vcc;
-
-		if (!vcc)
-			continue;
-
-		printk("%s: Connection %d:\n", card->name, vc->index);
-		dump_tct(card, vc->index);
-	}
-}
-#endif
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* SCQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-sb_pool_add(struct idt77252_dev *card, struct sk_buff *skb, int queue)
-{
-	struct sb_pool *pool = &card->sbpool[queue];
-	int index;
-
-	index = pool->index;
-	while (pool->skb[index]) {
-		index = (index + 1) & FBQ_MASK;
-		if (index == pool->index)
-			return -ENOBUFS;
-	}
-
-	pool->skb[index] = skb;
-	IDT77252_PRV_POOL(skb) = POOL_HANDLE(queue, index);
-
-	pool->index = (index + 1) & FBQ_MASK;
-	return 0;
-}
-
-static void
-sb_pool_remove(struct idt77252_dev *card, struct sk_buff *skb)
-{
-	unsigned int queue, index;
-	u32 handle;
-
-	handle = IDT77252_PRV_POOL(skb);
-
-	queue = POOL_QUEUE(handle);
-	if (queue > 3)
-		return;
-
-	index = POOL_INDEX(handle);
-	if (index > FBQ_SIZE - 1)
-		return;
-
-	card->sbpool[queue].skb[index] = NULL;
-}
-
-static struct sk_buff *
-sb_pool_skb(struct idt77252_dev *card, u32 handle)
-{
-	unsigned int queue, index;
-
-	queue = POOL_QUEUE(handle);
-	if (queue > 3)
-		return NULL;
-
-	index = POOL_INDEX(handle);
-	if (index > FBQ_SIZE - 1)
-		return NULL;
-
-	return card->sbpool[queue].skb[index];
-}
-
-static struct scq_info *
-alloc_scq(struct idt77252_dev *card, int class)
-{
-	struct scq_info *scq;
-
-	scq = kzalloc_obj(struct scq_info);
-	if (!scq)
-		return NULL;
-	scq->base = dma_alloc_coherent(&card->pcidev->dev, SCQ_SIZE,
-				       &scq->paddr, GFP_KERNEL);
-	if (scq->base == NULL) {
-		kfree(scq);
-		return NULL;
-	}
-
-	scq->next = scq->base;
-	scq->last = scq->base + (SCQ_ENTRIES - 1);
-	atomic_set(&scq->used, 0);
-
-	spin_lock_init(&scq->lock);
-	spin_lock_init(&scq->skblock);
-
-	skb_queue_head_init(&scq->transmit);
-	skb_queue_head_init(&scq->pending);
-
-	TXPRINTK("idt77252: SCQ: base 0x%p, next 0x%p, last 0x%p, paddr %08llx\n",
-		 scq->base, scq->next, scq->last, (unsigned long long)scq->paddr);
-
-	return scq;
-}
-
-static void
-free_scq(struct idt77252_dev *card, struct scq_info *scq)
-{
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	dma_free_coherent(&card->pcidev->dev, SCQ_SIZE,
-			  scq->base, scq->paddr);
-
-	while ((skb = skb_dequeue(&scq->transmit))) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-	}
-
-	while ((skb = skb_dequeue(&scq->pending))) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-	}
-
-	kfree(scq);
-}
-
-
-static int
-push_on_scq(struct idt77252_dev *card, struct vc_map *vc, struct sk_buff *skb)
-{
-	struct scq_info *scq = vc->scq;
-	unsigned long flags;
-	struct scqe *tbd;
-	int entries;
-
-	TXPRINTK("%s: SCQ: next 0x%p\n", card->name, scq->next);
-
-	atomic_inc(&scq->used);
-	entries = atomic_read(&scq->used);
-	if (entries > (SCQ_ENTRIES - 1)) {
-		atomic_dec(&scq->used);
-		goto out;
-	}
-
-	skb_queue_tail(&scq->transmit, skb);
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (vc->estimator) {
-		struct atm_vcc *vcc = vc->tx_vcc;
-		struct sock *sk = sk_atm(vcc);
-
-		vc->estimator->cells += (skb->len + 47) / 48;
-		if (refcount_read(&sk->sk_wmem_alloc) >
-		    (sk->sk_sndbuf >> 1)) {
-			u32 cps = vc->estimator->maxcps;
-
-			vc->estimator->cps = cps;
-			vc->estimator->avcps = cps << 5;
-			if (vc->lacr < vc->init_er) {
-				vc->lacr = vc->init_er;
-				writel(TCMDQ_LACR | (vc->lacr << 16) |
-				       vc->index, SAR_REG_TCMDQ);
-			}
-		}
-	}
-	spin_unlock_irqrestore(&vc->lock, flags);
-
-	tbd = &IDT77252_PRV_TBD(skb);
-
-	spin_lock_irqsave(&scq->lock, flags);
-	scq->next->word_1 = cpu_to_le32(tbd->word_1 |
-					SAR_TBD_TSIF | SAR_TBD_GTSI);
-	scq->next->word_2 = cpu_to_le32(tbd->word_2);
-	scq->next->word_3 = cpu_to_le32(tbd->word_3);
-	scq->next->word_4 = cpu_to_le32(tbd->word_4);
-
-	if (scq->next == scq->last)
-		scq->next = scq->base;
-	else
-		scq->next++;
-
-	write_sram(card, scq->scd,
-		   scq->paddr +
-		   (u32)((unsigned long)scq->next - (unsigned long)scq->base));
-	spin_unlock_irqrestore(&scq->lock, flags);
-
-	scq->trans_start = jiffies;
-
-	if (test_and_clear_bit(VCF_IDLE, &vc->flags)) {
-		writel(TCMDQ_START_LACR | (vc->lacr << 16) | vc->index,
-		       SAR_REG_TCMDQ);
-	}
-
-	TXPRINTK("%d entries in SCQ used (push).\n", atomic_read(&scq->used));
-
-	XPRINTK("%s: SCQ (after push %2d) head = 0x%x, next = 0x%p.\n",
-		card->name, atomic_read(&scq->used),
-		read_sram(card, scq->scd + 1), scq->next);
-
-	return 0;
-
-out:
-	if (time_after(jiffies, scq->trans_start + HZ)) {
-		printk("%s: Error pushing TBD for %d.%d\n",
-		       card->name, vc->tx_vcc->vpi, vc->tx_vcc->vci);
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		idt77252_tx_dump(card);
-#endif
-		scq->trans_start = jiffies;
-	}
-
-	return -ENOBUFS;
-}
-
-
-static void
-drain_scq(struct idt77252_dev *card, struct vc_map *vc)
-{
-	struct scq_info *scq = vc->scq;
-	struct sk_buff *skb;
-	struct atm_vcc *vcc;
-
-	TXPRINTK("%s: SCQ (before drain %2d) next = 0x%p.\n",
-		 card->name, atomic_read(&scq->used), scq->next);
-
-	skb = skb_dequeue(&scq->transmit);
-	if (skb) {
-		TXPRINTK("%s: freeing skb at %p.\n", card->name, skb);
-
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb->len, DMA_TO_DEVICE);
-
-		vcc = ATM_SKB(skb)->vcc;
-
-		if (vcc->pop)
-			vcc->pop(vcc, skb);
-		else
-			dev_kfree_skb(skb);
-
-		atomic_inc(&vcc->stats->tx);
-	}
-
-	atomic_dec(&scq->used);
-
-	spin_lock(&scq->skblock);
-	while ((skb = skb_dequeue(&scq->pending))) {
-		if (push_on_scq(card, vc, skb)) {
-			skb_queue_head(&vc->scq->pending, skb);
-			break;
-		}
-	}
-	spin_unlock(&scq->skblock);
-}
-
-static int
-queue_skb(struct idt77252_dev *card, struct vc_map *vc,
-	  struct sk_buff *skb, int oam)
-{
-	struct atm_vcc *vcc;
-	struct scqe *tbd;
-	unsigned long flags;
-	int error;
-	int aal;
-	u32 word4;
-
-	if (skb->len == 0) {
-		printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
-		return -EINVAL;
-	}
-
-	TXPRINTK("%s: Sending %d bytes of data.\n",
-		 card->name, skb->len);
-
-	tbd = &IDT77252_PRV_TBD(skb);
-	vcc = ATM_SKB(skb)->vcc;
-	word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
-			(skb->data[2] <<  8) | (skb->data[3] <<  0);
-
-	IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
-						 skb->len, DMA_TO_DEVICE);
-	if (dma_mapping_error(&card->pcidev->dev, IDT77252_PRV_PADDR(skb)))
-		return -ENOMEM;
-
-	error = -EINVAL;
-
-	if (oam) {
-		if (skb->len != 52)
-			goto errout;
-
-		tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
-		tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
-		tbd->word_3 = 0x00000000;
-		tbd->word_4 = word4;
-
-		if (test_bit(VCF_RSV, &vc->flags))
-			vc = card->vcs[0];
-
-		goto done;
-	}
-
-	if (test_bit(VCF_RSV, &vc->flags)) {
-		printk("%s: Trying to transmit on reserved VC\n", card->name);
-		goto errout;
-	}
-
-	aal = vcc->qos.aal;
-
-	switch (aal) {
-	case ATM_AAL0:
-	case ATM_AAL34:
-		if (skb->len > 52)
-			goto errout;
-
-		if (aal == ATM_AAL0)
-			tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL0 |
-				      ATM_CELL_PAYLOAD;
-		else
-			tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL34 |
-				      ATM_CELL_PAYLOAD;
-
-		tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
-		tbd->word_3 = 0x00000000;
-		tbd->word_4 = word4;
-		break;
-
-	case ATM_AAL5:
-		tbd->word_1 = SAR_TBD_EPDU | SAR_TBD_AAL5 | skb->len;
-		tbd->word_2 = IDT77252_PRV_PADDR(skb);
-		tbd->word_3 = skb->len;
-		tbd->word_4 = (vcc->vpi << SAR_TBD_VPI_SHIFT) |
-			      (vcc->vci << SAR_TBD_VCI_SHIFT);
-		break;
-
-	case ATM_AAL1:
-	case ATM_AAL2:
-	default:
-		printk("%s: Traffic type not supported.\n", card->name);
-		error = -EPROTONOSUPPORT;
-		goto errout;
-	}
-
-done:
-	spin_lock_irqsave(&vc->scq->skblock, flags);
-	skb_queue_tail(&vc->scq->pending, skb);
-
-	while ((skb = skb_dequeue(&vc->scq->pending))) {
-		if (push_on_scq(card, vc, skb)) {
-			skb_queue_head(&vc->scq->pending, skb);
-			break;
-		}
-	}
-	spin_unlock_irqrestore(&vc->scq->skblock, flags);
-
-	return 0;
-
-errout:
-	dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-			 skb->len, DMA_TO_DEVICE);
-	return error;
-}
-
-static unsigned long
-get_free_scd(struct idt77252_dev *card, struct vc_map *vc)
-{
-	int i;
-
-	for (i = 0; i < card->scd_size; i++) {
-		if (!card->scd2vc[i]) {
-			card->scd2vc[i] = vc;
-			vc->scd_index = i;
-			return card->scd_base + i * SAR_SRAM_SCD_SIZE;
-		}
-	}
-	return 0;
-}
-
-static void
-fill_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
-{
-	write_sram(card, scq->scd, scq->paddr);
-	write_sram(card, scq->scd + 1, 0x00000000);
-	write_sram(card, scq->scd + 2, 0xffffffff);
-	write_sram(card, scq->scd + 3, 0x00000000);
-}
-
-static void
-clear_scd(struct idt77252_dev *card, struct scq_info *scq, int class)
-{
-	return;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* RSQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-init_rsq(struct idt77252_dev *card)
-{
-	struct rsq_entry *rsqe;
-
-	card->rsq.base = dma_alloc_coherent(&card->pcidev->dev, RSQSIZE,
-					    &card->rsq.paddr, GFP_KERNEL);
-	if (card->rsq.base == NULL) {
-		printk("%s: can't allocate RSQ.\n", card->name);
-		return -1;
-	}
-
-	card->rsq.last = card->rsq.base + RSQ_NUM_ENTRIES - 1;
-	card->rsq.next = card->rsq.last;
-	for (rsqe = card->rsq.base; rsqe <= card->rsq.last; rsqe++)
-		rsqe->word_4 = 0;
-
-	writel((unsigned long) card->rsq.last - (unsigned long) card->rsq.base,
-	       SAR_REG_RSQH);
-	writel(card->rsq.paddr, SAR_REG_RSQB);
-
-	IPRINTK("%s: RSQ base at 0x%lx (0x%x).\n", card->name,
-		(unsigned long) card->rsq.base,
-		readl(SAR_REG_RSQB));
-	IPRINTK("%s: RSQ head = 0x%x, base = 0x%x, tail = 0x%x.\n",
-		card->name,
-		readl(SAR_REG_RSQH),
-		readl(SAR_REG_RSQB),
-		readl(SAR_REG_RSQT));
-
-	return 0;
-}
-
-static void
-deinit_rsq(struct idt77252_dev *card)
-{
-	dma_free_coherent(&card->pcidev->dev, RSQSIZE,
-			  card->rsq.base, card->rsq.paddr);
-}
-
-static void
-dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
-{
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	struct rx_pool *rpp;
-	struct vc_map *vc;
-	u32 header, vpi, vci;
-	u32 stat;
-	int i;
-
-	stat = le32_to_cpu(rsqe->word_4);
-
-	if (stat & SAR_RSQE_IDLE) {
-		RXPRINTK("%s: message about inactive connection.\n",
-			 card->name);
-		return;
-	}
-
-	skb = sb_pool_skb(card, le32_to_cpu(rsqe->word_2));
-	if (skb == NULL) {
-		printk("%s: NULL skb in %s, rsqe: %08x %08x %08x %08x\n",
-		       card->name, __func__,
-		       le32_to_cpu(rsqe->word_1), le32_to_cpu(rsqe->word_2),
-		       le32_to_cpu(rsqe->word_3), le32_to_cpu(rsqe->word_4));
-		return;
-	}
-
-	header = le32_to_cpu(rsqe->word_1);
-	vpi = (header >> 16) & 0x00ff;
-	vci = (header >>  0) & 0xffff;
-
-	RXPRINTK("%s: SDU for %d.%d received in buffer 0x%p (data 0x%p).\n",
-		 card->name, vpi, vci, skb, skb->data);
-
-	if ((vpi >= (1 << card->vpibits)) || (vci != (vci & card->vcimask))) {
-		printk("%s: SDU received for out-of-range vc %u.%u\n",
-		       card->name, vpi, vci);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-
-	vc = card->vcs[VPCI2VC(card, vpi, vci)];
-	if (!vc || !test_bit(VCF_RX, &vc->flags)) {
-		printk("%s: SDU received on non RX vc %u.%u\n",
-		       card->name, vpi, vci);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-
-	vcc = vc->rx_vcc;
-
-	dma_sync_single_for_cpu(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				skb_end_pointer(skb) - skb->data,
-				DMA_FROM_DEVICE);
-
-	if ((vcc->qos.aal == ATM_AAL0) ||
-	    (vcc->qos.aal == ATM_AAL34)) {
-		struct sk_buff *sb;
-		unsigned char *cell;
-		u32 aal0;
-
-		cell = skb->data;
-		for (i = (stat & SAR_RSQE_CELLCNT); i; i--) {
-			if ((sb = dev_alloc_skb(64)) == NULL) {
-				printk("%s: Can't allocate buffers for aal0.\n",
-				       card->name);
-				atomic_add(i, &vcc->stats->rx_drop);
-				break;
-			}
-			if (!atm_charge(vcc, sb->truesize)) {
-				RXPRINTK("%s: atm_charge() dropped aal0 packets.\n",
-					 card->name);
-				atomic_add(i - 1, &vcc->stats->rx_drop);
-				dev_kfree_skb(sb);
-				break;
-			}
-			aal0 = (vpi << ATM_HDR_VPI_SHIFT) |
-			       (vci << ATM_HDR_VCI_SHIFT);
-			aal0 |= (stat & SAR_RSQE_EPDU) ? 0x00000002 : 0;
-			aal0 |= (stat & SAR_RSQE_CLP)  ? 0x00000001 : 0;
-
-			*((u32 *) sb->data) = aal0;
-			skb_put(sb, sizeof(u32));
-			skb_put_data(sb, cell, ATM_CELL_PAYLOAD);
-
-			ATM_SKB(sb)->vcc = vcc;
-			__net_timestamp(sb);
-			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
-
-			cell += ATM_CELL_PAYLOAD;
-		}
-
-		recycle_rx_skb(card, skb);
-		return;
-	}
-	if (vcc->qos.aal != ATM_AAL5) {
-		printk("%s: Unexpected AAL type in dequeue_rx(): %d.\n",
-		       card->name, vcc->qos.aal);
-		recycle_rx_skb(card, skb);
-		return;
-	}
-	skb->len = (stat & SAR_RSQE_CELLCNT) * ATM_CELL_PAYLOAD;
-
-	rpp = &vc->rcv.rx_pool;
-
-	__skb_queue_tail(&rpp->queue, skb);
-	rpp->len += skb->len;
-
-	if (stat & SAR_RSQE_EPDU) {
-		unsigned int len, truesize;
-		unsigned char *l1l2;
-
-		l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6);
-
-		len = (l1l2[0] << 8) | l1l2[1];
-		len = len ? len : 0x10000;
-
-		RXPRINTK("%s: PDU has %d bytes.\n", card->name, len);
-
-		if ((len + 8 > rpp->len) || (len + (47 + 8) < rpp->len)) {
-			RXPRINTK("%s: AAL5 PDU size mismatch: %d != %d. "
-			         "(CDC: %08x)\n",
-			         card->name, len, rpp->len, readl(SAR_REG_CDC));
-			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
-			return;
-		}
-		if (stat & SAR_RSQE_CRC) {
-			RXPRINTK("%s: AAL5 CRC error.\n", card->name);
-			recycle_rx_pool_skb(card, rpp);
-			atomic_inc(&vcc->stats->rx_err);
-			return;
-		}
-		if (skb_queue_len(&rpp->queue) > 1) {
-			struct sk_buff *sb;
-
-			skb = dev_alloc_skb(rpp->len);
-			if (!skb) {
-				RXPRINTK("%s: Can't alloc RX skb.\n",
-					 card->name);
-				recycle_rx_pool_skb(card, rpp);
-				atomic_inc(&vcc->stats->rx_err);
-				return;
-			}
-			if (!atm_charge(vcc, skb->truesize)) {
-				recycle_rx_pool_skb(card, rpp);
-				dev_kfree_skb(skb);
-				return;
-			}
-			skb_queue_walk(&rpp->queue, sb)
-				skb_put_data(skb, sb->data, sb->len);
-
-			recycle_rx_pool_skb(card, rpp);
-
-			skb_trim(skb, len);
-			ATM_SKB(skb)->vcc = vcc;
-			__net_timestamp(skb);
-
-			vcc->push(vcc, skb);
-			atomic_inc(&vcc->stats->rx);
-
-			return;
-		}
-
-		flush_rx_pool(card, rpp);
-
-		if (!atm_charge(vcc, skb->truesize)) {
-			recycle_rx_skb(card, skb);
-			return;
-		}
-
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb_end_pointer(skb) - skb->data,
-				 DMA_FROM_DEVICE);
-		sb_pool_remove(card, skb);
-
-		skb_trim(skb, len);
-		ATM_SKB(skb)->vcc = vcc;
-		__net_timestamp(skb);
-
-		truesize = skb->truesize;
-		vcc->push(vcc, skb);
-		atomic_inc(&vcc->stats->rx);
-
-		if (truesize > SAR_FB_SIZE_3)
-			add_rx_skb(card, 3, SAR_FB_SIZE_3, 1);
-		else if (truesize > SAR_FB_SIZE_2)
-			add_rx_skb(card, 2, SAR_FB_SIZE_2, 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);
-		return;
-	}
-}
-
-static void
-idt77252_rx(struct idt77252_dev *card)
-{
-	struct rsq_entry *rsqe;
-
-	if (card->rsq.next == card->rsq.last)
-		rsqe = card->rsq.base;
-	else
-		rsqe = card->rsq.next + 1;
-
-	if (!(le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID)) {
-		RXPRINTK("%s: no entry in RSQ.\n", card->name);
-		return;
-	}
-
-	do {
-		dequeue_rx(card, rsqe);
-		rsqe->word_4 = 0;
-		card->rsq.next = rsqe;
-		if (card->rsq.next == card->rsq.last)
-			rsqe = card->rsq.base;
-		else
-			rsqe = card->rsq.next + 1;
-	} while (le32_to_cpu(rsqe->word_4) & SAR_RSQE_VALID);
-
-	writel((unsigned long) card->rsq.next - (unsigned long) card->rsq.base,
-	       SAR_REG_RSQH);
-}
-
-static void
-idt77252_rx_raw(struct idt77252_dev *card)
-{
-	struct sk_buff	*queue;
-	u32		head, tail;
-	struct atm_vcc	*vcc;
-	struct vc_map	*vc;
-	struct sk_buff	*sb;
-
-	if (card->raw_cell_head == NULL) {
-		u32 handle = le32_to_cpu(*(card->raw_cell_hnd + 1));
-		card->raw_cell_head = sb_pool_skb(card, handle);
-	}
-
-	queue = card->raw_cell_head;
-	if (!queue)
-		return;
-
-	head = IDT77252_PRV_PADDR(queue) + (queue->data - queue->head - 16);
-	tail = readl(SAR_REG_RAWCT);
-
-	dma_sync_single_for_cpu(&card->pcidev->dev, IDT77252_PRV_PADDR(queue),
-				skb_end_offset(queue) - 16,
-				DMA_FROM_DEVICE);
-
-	while (head != tail) {
-		unsigned int vpi, vci;
-		u32 header;
-
-		header = le32_to_cpu(*(u32 *) &queue->data[0]);
-
-		vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
-		vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		if (debug & DBG_RAW_CELL) {
-			int i;
-
-			printk("%s: raw cell %x.%02x.%04x.%x.%x\n",
-			       card->name, (header >> 28) & 0x000f,
-			       (header >> 20) & 0x00ff,
-			       (header >>  4) & 0xffff,
-			       (header >>  1) & 0x0007,
-			       (header >>  0) & 0x0001);
-			for (i = 16; i < 64; i++)
-				printk(" %02x", queue->data[i]);
-			printk("\n");
-		}
-#endif
-
-		if (vpi >= (1<<card->vpibits) || vci >= (1<<card->vcibits)) {
-			RPRINTK("%s: SDU received for out-of-range vc %u.%u\n",
-				card->name, vpi, vci);
-			goto drop;
-		}
-
-		vc = card->vcs[VPCI2VC(card, vpi, vci)];
-		if (!vc || !test_bit(VCF_RX, &vc->flags)) {
-			RPRINTK("%s: SDU received on non RX vc %u.%u\n",
-				card->name, vpi, vci);
-			goto drop;
-		}
-
-		vcc = vc->rx_vcc;
-
-		if (vcc->qos.aal != ATM_AAL0) {
-			RPRINTK("%s: raw cell for non AAL0 vc %u.%u\n",
-				card->name, vpi, vci);
-			atomic_inc(&vcc->stats->rx_drop);
-			goto drop;
-		}
-	
-		if ((sb = dev_alloc_skb(64)) == NULL) {
-			printk("%s: Can't allocate buffers for AAL0.\n",
-			       card->name);
-			atomic_inc(&vcc->stats->rx_err);
-			goto drop;
-		}
-
-		if (!atm_charge(vcc, sb->truesize)) {
-			RXPRINTK("%s: atm_charge() dropped AAL0 packets.\n",
-				 card->name);
-			dev_kfree_skb(sb);
-			goto drop;
-		}
-
-		*((u32 *) sb->data) = header;
-		skb_put(sb, sizeof(u32));
-		skb_put_data(sb, &(queue->data[16]), ATM_CELL_PAYLOAD);
-
-		ATM_SKB(sb)->vcc = vcc;
-		__net_timestamp(sb);
-		vcc->push(vcc, sb);
-		atomic_inc(&vcc->stats->rx);
-
-drop:
-		skb_pull(queue, 64);
-
-		head = IDT77252_PRV_PADDR(queue)
-					+ (queue->data - queue->head - 16);
-
-		if (queue->len < 128) {
-			struct sk_buff *next;
-			u32 handle;
-
-			head = le32_to_cpu(*(u32 *) &queue->data[0]);
-			handle = le32_to_cpu(*(u32 *) &queue->data[4]);
-
-			next = sb_pool_skb(card, handle);
-			recycle_rx_skb(card, queue);
-
-			if (next) {
-				card->raw_cell_head = next;
-				queue = card->raw_cell_head;
-				dma_sync_single_for_cpu(&card->pcidev->dev,
-							IDT77252_PRV_PADDR(queue),
-							(skb_end_pointer(queue) -
-							 queue->data),
-							DMA_FROM_DEVICE);
-			} else {
-				card->raw_cell_head = NULL;
-				printk("%s: raw cell queue overrun\n",
-				       card->name);
-				break;
-			}
-		}
-	}
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* TSQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static int
-init_tsq(struct idt77252_dev *card)
-{
-	struct tsq_entry *tsqe;
-
-	card->tsq.base = dma_alloc_coherent(&card->pcidev->dev, RSQSIZE,
-					    &card->tsq.paddr, GFP_KERNEL);
-	if (card->tsq.base == NULL) {
-		printk("%s: can't allocate TSQ.\n", card->name);
-		return -1;
-	}
-
-	card->tsq.last = card->tsq.base + TSQ_NUM_ENTRIES - 1;
-	card->tsq.next = card->tsq.last;
-	for (tsqe = card->tsq.base; tsqe <= card->tsq.last; tsqe++)
-		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);
-
-	writel(card->tsq.paddr, SAR_REG_TSQB);
-	writel((unsigned long) card->tsq.next - (unsigned long) card->tsq.base,
-	       SAR_REG_TSQH);
-
-	return 0;
-}
-
-static void
-deinit_tsq(struct idt77252_dev *card)
-{
-	dma_free_coherent(&card->pcidev->dev, TSQSIZE,
-			  card->tsq.base, card->tsq.paddr);
-}
-
-static void
-idt77252_tx(struct idt77252_dev *card)
-{
-	struct tsq_entry *tsqe;
-	unsigned int vpi, vci;
-	struct vc_map *vc;
-	u32 conn, stat;
-
-	if (card->tsq.next == card->tsq.last)
-		tsqe = card->tsq.base;
-	else
-		tsqe = card->tsq.next + 1;
-
-	TXPRINTK("idt77252_tx: tsq  %p: base %p, next %p, last %p\n", tsqe,
-		 card->tsq.base, card->tsq.next, card->tsq.last);
-	TXPRINTK("idt77252_tx: tsqb %08x, tsqt %08x, tsqh %08x, \n",
-		 readl(SAR_REG_TSQB),
-		 readl(SAR_REG_TSQT),
-		 readl(SAR_REG_TSQH));
-
-	stat = le32_to_cpu(tsqe->word_2);
-
-	if (stat & SAR_TSQE_INVALID)
-		return;
-
-	do {
-		TXPRINTK("tsqe: 0x%p [0x%08x 0x%08x]\n", tsqe,
-			 le32_to_cpu(tsqe->word_1),
-			 le32_to_cpu(tsqe->word_2));
-
-		switch (stat & SAR_TSQE_TYPE) {
-		case SAR_TSQE_TYPE_TIMER:
-			TXPRINTK("%s: Timer RollOver detected.\n", card->name);
-			break;
-
-		case SAR_TSQE_TYPE_IDLE:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			if (SAR_TSQE_TAG(stat) == 0x10) {
-#ifdef	NOTDEF
-				printk("%s: Connection %d halted.\n",
-				       card->name,
-				       le32_to_cpu(tsqe->word_1) & 0x1fff);
-#endif
-				break;
-			}
-
-			vc = card->vcs[conn & 0x1fff];
-			if (!vc) {
-				printk("%s: could not find VC from conn %d\n",
-				       card->name, conn & 0x1fff);
-				break;
-			}
-
-			printk("%s: Connection %d IDLE.\n",
-			       card->name, vc->index);
-
-			set_bit(VCF_IDLE, &vc->flags);
-			break;
-
-		case SAR_TSQE_TYPE_TSR:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			vc = card->vcs[conn & 0x1fff];
-			if (!vc) {
-				printk("%s: no VC at index %d\n",
-				       card->name,
-				       le32_to_cpu(tsqe->word_1) & 0x1fff);
-				break;
-			}
-
-			drain_scq(card, vc);
-			break;
-
-		case SAR_TSQE_TYPE_TBD_COMP:
-
-			conn = le32_to_cpu(tsqe->word_1);
-
-			vpi = (conn >> SAR_TBD_VPI_SHIFT) & 0x00ff;
-			vci = (conn >> SAR_TBD_VCI_SHIFT) & 0xffff;
-
-			if (vpi >= (1 << card->vpibits) ||
-			    vci >= (1 << card->vcibits)) {
-				printk("%s: TBD complete: "
-				       "out of range VPI.VCI %u.%u\n",
-				       card->name, vpi, vci);
-				break;
-			}
-
-			vc = card->vcs[VPCI2VC(card, vpi, vci)];
-			if (!vc) {
-				printk("%s: TBD complete: "
-				       "no VC at VPI.VCI %u.%u\n",
-				       card->name, vpi, vci);
-				break;
-			}
-
-			drain_scq(card, vc);
-			break;
-		}
-
-		tsqe->word_2 = cpu_to_le32(SAR_TSQE_INVALID);
-
-		card->tsq.next = tsqe;
-		if (card->tsq.next == card->tsq.last)
-			tsqe = card->tsq.base;
-		else
-			tsqe = card->tsq.next + 1;
-
-		TXPRINTK("tsqe: %p: base %p, next %p, last %p\n", tsqe,
-			 card->tsq.base, card->tsq.next, card->tsq.last);
-
-		stat = le32_to_cpu(tsqe->word_2);
-
-	} while (!(stat & SAR_TSQE_INVALID));
-
-	writel((unsigned long)card->tsq.next - (unsigned long)card->tsq.base,
-	       SAR_REG_TSQH);
-
-	XPRINTK("idt77252_tx-after writel%d: TSQ head = 0x%x, tail = 0x%x, next = 0x%p.\n",
-		card->index, readl(SAR_REG_TSQH),
-		readl(SAR_REG_TSQT), card->tsq.next);
-}
-
-
-static void
-tst_timer(struct timer_list *t)
-{
-	struct idt77252_dev *card = timer_container_of(card, t, tst_timer);
-	unsigned long base, idle, jump;
-	unsigned long flags;
-	u32 pc;
-	int e;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	base = card->tst[card->tst_index];
-	idle = card->tst[card->tst_index ^ 1];
-
-	if (test_bit(TST_SWITCH_WAIT, &card->tst_state)) {
-		jump = base + card->tst_size - 2;
-
-		pc = readl(SAR_REG_NOW) >> 2;
-		if ((pc ^ idle) & ~(card->tst_size - 1)) {
-			mod_timer(&card->tst_timer, jiffies + 1);
-			goto out;
-		}
-
-		clear_bit(TST_SWITCH_WAIT, &card->tst_state);
-
-		card->tst_index ^= 1;
-		write_sram(card, jump, TSTE_OPC_JMP | (base << 2));
-
-		base = card->tst[card->tst_index];
-		idle = card->tst[card->tst_index ^ 1];
-
-		for (e = 0; e < card->tst_size - 2; e++) {
-			if (card->soft_tst[e].tste & TSTE_PUSH_IDLE) {
-				write_sram(card, idle + e,
-					   card->soft_tst[e].tste & TSTE_MASK);
-				card->soft_tst[e].tste &= ~(TSTE_PUSH_IDLE);
-			}
-		}
-	}
-
-	if (test_and_clear_bit(TST_SWITCH_PENDING, &card->tst_state)) {
-
-		for (e = 0; e < card->tst_size - 2; e++) {
-			if (card->soft_tst[e].tste & TSTE_PUSH_ACTIVE) {
-				write_sram(card, idle + e,
-					   card->soft_tst[e].tste & TSTE_MASK);
-				card->soft_tst[e].tste &= ~(TSTE_PUSH_ACTIVE);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-		}
-
-		jump = base + card->tst_size - 2;
-
-		write_sram(card, jump, TSTE_OPC_NULL);
-		set_bit(TST_SWITCH_WAIT, &card->tst_state);
-
-		mod_timer(&card->tst_timer, jiffies + 1);
-	}
-
-out:
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-}
-
-static int
-__fill_tst(struct idt77252_dev *card, struct vc_map *vc,
-	   int n, unsigned int opc)
-{
-	unsigned long cl, avail;
-	unsigned long idle;
-	int e, r;
-	u32 data;
-
-	avail = card->tst_size - 2;
-	for (e = 0; e < avail; e++) {
-		if (card->soft_tst[e].vc == NULL)
-			break;
-	}
-	if (e >= avail) {
-		printk("%s: No free TST entries found\n", card->name);
-		return -1;
-	}
-
-	NPRINTK("%s: conn %d: first TST entry at %d.\n",
-		card->name, vc ? vc->index : -1, e);
-
-	r = n;
-	cl = avail;
-	data = opc & TSTE_OPC_MASK;
-	if (vc && (opc != TSTE_OPC_NULL))
-		data = opc | vc->index;
-
-	idle = card->tst[card->tst_index ^ 1];
-
-	/*
-	 * Fill Soft TST.
-	 */
-	while (r > 0) {
-		if ((cl >= avail) && (card->soft_tst[e].vc == NULL)) {
-			if (vc)
-				card->soft_tst[e].vc = vc;
-			else
-				card->soft_tst[e].vc = (void *)-1;
-
-			card->soft_tst[e].tste = data;
-			if (timer_pending(&card->tst_timer))
-				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;
-			else {
-				write_sram(card, idle + e, data);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-
-			cl -= card->tst_size;
-			r--;
-		}
-
-		if (++e == avail)
-			e = 0;
-		cl += n;
-	}
-
-	return 0;
-}
-
-static int
-fill_tst(struct idt77252_dev *card, struct vc_map *vc, int n, unsigned int opc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	res = __fill_tst(card, vc, n, opc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-static int
-__clear_tst(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long idle;
-	int e;
-
-	idle = card->tst[card->tst_index ^ 1];
-
-	for (e = 0; e < card->tst_size - 2; e++) {
-		if (card->soft_tst[e].vc == vc) {
-			card->soft_tst[e].vc = NULL;
-
-			card->soft_tst[e].tste = TSTE_OPC_VAR;
-			if (timer_pending(&card->tst_timer))
-				card->soft_tst[e].tste |= TSTE_PUSH_ACTIVE;
-			else {
-				write_sram(card, idle + e, TSTE_OPC_VAR);
-				card->soft_tst[e].tste |= TSTE_PUSH_IDLE;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int
-clear_tst(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	res = __clear_tst(card, vc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-static int
-change_tst(struct idt77252_dev *card, struct vc_map *vc,
-	   int n, unsigned int opc)
-{
-	unsigned long flags;
-	int res;
-
-	spin_lock_irqsave(&card->tst_lock, flags);
-
-	__clear_tst(card, vc);
-	res = __fill_tst(card, vc, n, opc);
-
-	set_bit(TST_SWITCH_PENDING, &card->tst_state);
-	if (!timer_pending(&card->tst_timer))
-		mod_timer(&card->tst_timer, jiffies + 1);
-
-	spin_unlock_irqrestore(&card->tst_lock, flags);
-	return res;
-}
-
-
-static int
-set_tct(struct idt77252_dev *card, struct vc_map *vc)
-{
-	unsigned long tct;
-
-	tct = (unsigned long) (card->tct_base + vc->index * SAR_SRAM_TCT_SIZE);
-
-	switch (vc->class) {
-	case SCHED_CBR:
-		OPRINTK("%s: writing TCT at 0x%lx, SCD 0x%lx.\n",
-		        card->name, tct, vc->scq->scd);
-
-		write_sram(card, tct + 0, TCT_CBR | vc->scq->scd);
-		write_sram(card, tct + 1, 0);
-		write_sram(card, tct + 2, 0);
-		write_sram(card, tct + 3, 0);
-		write_sram(card, tct + 4, 0);
-		write_sram(card, tct + 5, 0);
-		write_sram(card, tct + 6, 0);
-		write_sram(card, tct + 7, 0);
-		break;
-
-	case SCHED_UBR:
-		OPRINTK("%s: writing TCT at 0x%lx, SCD 0x%lx.\n",
-		        card->name, tct, vc->scq->scd);
-
-		write_sram(card, tct + 0, TCT_UBR | vc->scq->scd);
-		write_sram(card, tct + 1, 0);
-		write_sram(card, tct + 2, TCT_TSIF);
-		write_sram(card, tct + 3, TCT_HALT | TCT_IDLE);
-		write_sram(card, tct + 4, 0);
-		write_sram(card, tct + 5, vc->init_er);
-		write_sram(card, tct + 6, 0);
-		write_sram(card, tct + 7, TCT_FLAG_UBR);
-		break;
-
-	case SCHED_VBR:
-	case SCHED_ABR:
-	default:
-		return -ENOSYS;
-	}
-
-	return 0;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* FBQ Handling                                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-static __inline__ int
-idt77252_fbq_full(struct idt77252_dev *card, int queue)
-{
-	return (readl(SAR_REG_STAT) >> (16 + (queue << 2))) == 0x0f;
-}
-
-static int
-push_rx_skb(struct idt77252_dev *card, struct sk_buff *skb, int queue)
-{
-	unsigned long flags;
-	u32 handle;
-	u32 addr;
-
-	skb->data = skb->head;
-	skb_reset_tail_pointer(skb);
-	skb->len = 0;
-
-	skb_reserve(skb, 16);
-
-	switch (queue) {
-	case 0:
-		skb_put(skb, SAR_FB_SIZE_0);
-		break;
-	case 1:
-		skb_put(skb, SAR_FB_SIZE_1);
-		break;
-	case 2:
-		skb_put(skb, SAR_FB_SIZE_2);
-		break;
-	case 3:
-		skb_put(skb, SAR_FB_SIZE_3);
-		break;
-	default:
-		return -1;
-	}
-
-	if (idt77252_fbq_full(card, queue))
-		return -1;
-
-	memset(&skb->data[(skb->len & ~(0x3f)) - 64], 0, 2 * sizeof(u32));
-
-	handle = IDT77252_PRV_POOL(skb);
-	addr = IDT77252_PRV_PADDR(skb);
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(handle, card->fbq[queue]);
-	writel(addr, card->fbq[queue]);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-	return 0;
-}
-
-static void
-add_rx_skb(struct idt77252_dev *card, int queue,
-	   unsigned int size, unsigned int count)
-{
-	struct sk_buff *skb;
-	dma_addr_t paddr;
-
-	while (count--) {
-		skb = dev_alloc_skb(size);
-		if (!skb)
-			return;
-
-		if (sb_pool_add(card, skb, queue)) {
-			printk("%s: SB POOL full\n", __func__);
-			goto outfree;
-		}
-
-		paddr = dma_map_single(&card->pcidev->dev, skb->data,
-				       skb_end_pointer(skb) - skb->data,
-				       DMA_FROM_DEVICE);
-		if (dma_mapping_error(&card->pcidev->dev, paddr))
-			goto outpoolrm;
-		IDT77252_PRV_PADDR(skb) = paddr;
-
-		if (push_rx_skb(card, skb, queue)) {
-			printk("%s: FB QUEUE full\n", __func__);
-			goto outunmap;
-		}
-	}
-
-	return;
-
-outunmap:
-	dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-			 skb_end_pointer(skb) - skb->data, DMA_FROM_DEVICE);
-
-outpoolrm:
-	sb_pool_remove(card, skb);
-
-outfree:
-	dev_kfree_skb(skb);
-}
-
-
-static void
-recycle_rx_skb(struct idt77252_dev *card, struct sk_buff *skb)
-{
-	u32 handle = IDT77252_PRV_POOL(skb);
-	int err;
-
-	dma_sync_single_for_device(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				   skb_end_pointer(skb) - skb->data,
-				   DMA_FROM_DEVICE);
-
-	err = push_rx_skb(card, skb, POOL_QUEUE(handle));
-	if (err) {
-		dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb),
-				 skb_end_pointer(skb) - skb->data,
-				 DMA_FROM_DEVICE);
-		sb_pool_remove(card, skb);
-		dev_kfree_skb(skb);
-	}
-}
-
-static void
-flush_rx_pool(struct idt77252_dev *card, struct rx_pool *rpp)
-{
-	skb_queue_head_init(&rpp->queue);
-	rpp->len = 0;
-}
-
-static void
-recycle_rx_pool_skb(struct idt77252_dev *card, struct rx_pool *rpp)
-{
-	struct sk_buff *skb, *tmp;
-
-	skb_queue_walk_safe(&rpp->queue, skb, tmp)
-		recycle_rx_skb(card, skb);
-
-	flush_rx_pool(card, rpp);
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* ATM Interface                                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-idt77252_phy_put(struct atm_dev *dev, unsigned char value, unsigned long addr)
-{
-	write_utility(dev->dev_data, 0x100 + (addr & 0x1ff), value);
-}
-
-static unsigned char
-idt77252_phy_get(struct atm_dev *dev, unsigned long addr)
-{
-	return read_utility(dev->dev_data, 0x100 + (addr & 0x1ff));
-}
-
-static inline int
-idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	int err;
-
-	if (vc == NULL) {
-		printk("%s: NULL connection in send().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	if (!test_bit(VCF_TX, &vc->flags)) {
-		printk("%s: Trying to transmit on a non-tx VC.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-
-	switch (vcc->qos.aal) {
-	case ATM_AAL0:
-	case ATM_AAL1:
-	case ATM_AAL5:
-		break;
-	default:
-		printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-
-	if (skb_shinfo(skb)->nr_frags != 0) {
-		printk("%s: No scatter-gather yet.\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return -EINVAL;
-	}
-	ATM_SKB(skb)->vcc = vcc;
-
-	err = queue_skb(card, vc, skb, oam);
-	if (err) {
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb(skb);
-		return err;
-	}
-
-	return 0;
-}
-
-static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return idt77252_send_skb(vcc, skb, 0);
-}
-
-static int
-idt77252_send_oam(struct atm_vcc *vcc, void *cell, int flags)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct sk_buff *skb;
-
-	skb = dev_alloc_skb(64);
-	if (!skb) {
-		printk("%s: Out of memory in send_oam().\n", card->name);
-		atomic_inc(&vcc->stats->tx_err);
-		return -ENOMEM;
-	}
-	refcount_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
-
-	skb_put_data(skb, cell, 52);
-
-	return idt77252_send_skb(vcc, skb, 1);
-}
-
-static __inline__ unsigned int
-idt77252_fls(unsigned int x)
-{
-	int r = 1;
-
-	if (x == 0)
-		return 0;
-	if (x & 0xffff0000) {
-		x >>= 16;
-		r += 16;
-	}
-	if (x & 0xff00) {
-		x >>= 8;
-		r += 8;
-	}
-	if (x & 0xf0) {
-		x >>= 4;
-		r += 4;
-	}
-	if (x & 0xc) {
-		x >>= 2;
-		r += 2;
-	}
-	if (x & 0x2)
-		r += 1;
-	return r;
-}
-
-static u16
-idt77252_int_to_atmfp(unsigned int rate)
-{
-	u16 m, e;
-
-	if (rate == 0)
-		return 0;
-	e = idt77252_fls(rate) - 1;
-	if (e < 9)
-		m = (rate - (1 << e)) << (9 - e);
-	else if (e == 9)
-		m = (rate - (1 << e));
-	else /* e > 9 */
-		m = (rate - (1 << e)) >> (e - 9);
-	return 0x4000 | (e << 9) | m;
-}
-
-static u8
-idt77252_rate_logindex(struct idt77252_dev *card, int pcr)
-{
-	u16 afp;
-
-	afp = idt77252_int_to_atmfp(pcr < 0 ? -pcr : pcr);
-	if (pcr < 0)
-		return rate_to_log[(afp >> 5) & 0x1ff];
-	return rate_to_log[((afp >> 5) + 1) & 0x1ff];
-}
-
-static void
-idt77252_est_timer(struct timer_list *t)
-{
-	struct rate_estimator *est = timer_container_of(est, t, timer);
-	struct vc_map *vc = est->vc;
-	struct idt77252_dev *card = vc->card;
-	unsigned long flags;
-	u32 rate, cps;
-	u64 ncells;
-	u8 lacr;
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (!vc->estimator)
-		goto out;
-	ncells = est->cells;
-
-	rate = ((u32)(ncells - est->last_cells)) << (7 - est->interval);
-	est->last_cells = ncells;
-	est->avcps += ((long)rate - (long)est->avcps) >> est->ewma_log;
-	est->cps = (est->avcps + 0x1f) >> 5;
-
-	cps = est->cps;
-	if (cps < (est->maxcps >> 4))
-		cps = est->maxcps >> 4;
-
-	lacr = idt77252_rate_logindex(card, cps);
-	if (lacr > vc->max_er)
-		lacr = vc->max_er;
-
-	if (lacr != vc->lacr) {
-		vc->lacr = lacr;
-		writel(TCMDQ_LACR|(vc->lacr << 16)|vc->index, SAR_REG_TCMDQ);
-	}
-
-	est->timer.expires = jiffies + ((HZ / 4) << est->interval);
-	add_timer(&est->timer);
-
-out:
-	spin_unlock_irqrestore(&vc->lock, flags);
-}
-
-static struct rate_estimator *
-idt77252_init_est(struct vc_map *vc, int pcr)
-{
-	struct rate_estimator *est;
-
-	est = kzalloc_obj(struct rate_estimator);
-	if (!est)
-		return NULL;
-	est->maxcps = pcr < 0 ? -pcr : pcr;
-	est->cps = est->maxcps;
-	est->avcps = est->cps << 5;
-	est->vc = vc;
-
-	est->interval = 2;		/* XXX: make this configurable */
-	est->ewma_log = 2;		/* XXX: make this configurable */
-	timer_setup(&est->timer, idt77252_est_timer, 0);
-	mod_timer(&est->timer, jiffies + ((HZ / 4) << est->interval));
-
-	return est;
-}
-
-static int
-idt77252_init_cbr(struct idt77252_dev *card, struct vc_map *vc,
-		  struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	int tst_free, tst_used, tst_entries;
-	unsigned long tmpl, modl;
-	int tcr, tcra;
-
-	if ((qos->txtp.max_pcr == 0) &&
-	    (qos->txtp.pcr == 0) && (qos->txtp.min_pcr == 0)) {
-		printk("%s: trying to open a CBR VC with cell rate = 0\n",
-		       card->name);
-		return -EINVAL;
-	}
-
-	tst_used = 0;
-	tst_free = card->tst_free;
-	if (test_bit(VCF_TX, &vc->flags))
-		tst_used = vc->ntste;
-	tst_free += tst_used;
-
-	tcr = atm_pcr_goal(&qos->txtp);
-	tcra = tcr >= 0 ? tcr : -tcr;
-
-	TXPRINTK("%s: CBR target cell rate = %d\n", card->name, tcra);
-
-	tmpl = (unsigned long) tcra * ((unsigned long) card->tst_size - 2);
-	modl = tmpl % (unsigned long)card->utopia_pcr;
-
-	tst_entries = (int) (tmpl / card->utopia_pcr);
-	if (tcr > 0) {
-		if (modl > 0)
-			tst_entries++;
-	} else if (tcr == 0) {
-		tst_entries = tst_free - SAR_TST_RESERVED;
-		if (tst_entries <= 0) {
-			printk("%s: no CBR bandwidth free.\n", card->name);
-			return -ENOSR;
-		}
-	}
-
-	if (tst_entries == 0) {
-		printk("%s: selected CBR bandwidth < granularity.\n",
-		       card->name);
-		return -EINVAL;
-	}
-
-	if (tst_entries > (tst_free - SAR_TST_RESERVED)) {
-		printk("%s: not enough CBR bandwidth free.\n", card->name);
-		return -ENOSR;
-	}
-
-	vc->ntste = tst_entries;
-
-	card->tst_free = tst_free - tst_entries;
-	if (test_bit(VCF_TX, &vc->flags)) {
-		if (tst_used == tst_entries)
-			return 0;
-
-		OPRINTK("%s: modify %d -> %d entries in TST.\n",
-			card->name, tst_used, tst_entries);
-		change_tst(card, vc, tst_entries, TSTE_OPC_CBR);
-		return 0;
-	}
-
-	OPRINTK("%s: setting %d entries in TST.\n", card->name, tst_entries);
-	fill_tst(card, vc, tst_entries, TSTE_OPC_CBR);
-	return 0;
-}
-
-static int
-idt77252_init_ubr(struct idt77252_dev *card, struct vc_map *vc,
-		  struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	struct rate_estimator *est = NULL;
-	unsigned long flags;
-	int tcr;
-
-	spin_lock_irqsave(&vc->lock, flags);
-	if (vc->estimator) {
-		est = vc->estimator;
-		vc->estimator = NULL;
-	}
-	spin_unlock_irqrestore(&vc->lock, flags);
-	if (est) {
-		timer_shutdown_sync(&est->timer);
-		kfree(est);
-	}
-
-	tcr = atm_pcr_goal(&qos->txtp);
-	if (tcr == 0)
-		tcr = card->link_pcr;
-
-	vc->estimator = idt77252_init_est(vc, tcr);
-
-	vc->class = SCHED_UBR;
-	vc->init_er = idt77252_rate_logindex(card, tcr);
-	vc->lacr = vc->init_er;
-	if (tcr < 0)
-		vc->max_er = vc->init_er;
-	else
-		vc->max_er = 0xff;
-
-	return 0;
-}
-
-static int
-idt77252_init_tx(struct idt77252_dev *card, struct vc_map *vc,
-		 struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	int error;
-
-	if (test_bit(VCF_TX, &vc->flags))
-		return -EBUSY;
-
-	switch (qos->txtp.traffic_class) {
-		case ATM_CBR:
-			vc->class = SCHED_CBR;
-			break;
-
-		case ATM_UBR:
-			vc->class = SCHED_UBR;
-			break;
-
-		case ATM_VBR:
-		case ATM_ABR:
-		default:
-			return -EPROTONOSUPPORT;
-	}
-
-	vc->scq = alloc_scq(card, vc->class);
-	if (!vc->scq) {
-		printk("%s: can't get SCQ.\n", card->name);
-		return -ENOMEM;
-	}
-
-	vc->scq->scd = get_free_scd(card, vc);
-	if (vc->scq->scd == 0) {
-		printk("%s: no SCD available.\n", card->name);
-		free_scq(card, vc->scq);
-		return -ENOMEM;
-	}
-
-	fill_scd(card, vc->scq, vc->class);
-
-	if (set_tct(card, vc)) {
-		printk("%s: class %d not supported.\n",
-		       card->name, qos->txtp.traffic_class);
-
-		card->scd2vc[vc->scd_index] = NULL;
-		free_scq(card, vc->scq);
-		return -EPROTONOSUPPORT;
-	}
-
-	switch (vc->class) {
-		case SCHED_CBR:
-			error = idt77252_init_cbr(card, vc, vcc, qos);
-			if (error) {
-				card->scd2vc[vc->scd_index] = NULL;
-				free_scq(card, vc->scq);
-				return error;
-			}
-
-			clear_bit(VCF_IDLE, &vc->flags);
-			writel(TCMDQ_START | vc->index, SAR_REG_TCMDQ);
-			break;
-
-		case SCHED_UBR:
-			error = idt77252_init_ubr(card, vc, vcc, qos);
-			if (error) {
-				card->scd2vc[vc->scd_index] = NULL;
-				free_scq(card, vc->scq);
-				return error;
-			}
-
-			set_bit(VCF_IDLE, &vc->flags);
-			break;
-	}
-
-	vc->tx_vcc = vcc;
-	set_bit(VCF_TX, &vc->flags);
-	return 0;
-}
-
-static int
-idt77252_init_rx(struct idt77252_dev *card, struct vc_map *vc,
-		 struct atm_vcc *vcc, struct atm_qos *qos)
-{
-	unsigned long flags;
-	unsigned long addr;
-	u32 rcte = 0;
-
-	if (test_bit(VCF_RX, &vc->flags))
-		return -EBUSY;
-
-	vc->rx_vcc = vcc;
-	set_bit(VCF_RX, &vc->flags);
-
-	if ((vcc->vci == 3) || (vcc->vci == 4))
-		return 0;
-
-	flush_rx_pool(card, &vc->rcv.rx_pool);
-
-	rcte |= SAR_RCTE_CONNECTOPEN;
-	rcte |= SAR_RCTE_RAWCELLINTEN;
-
-	switch (qos->aal) {
-		case ATM_AAL0:
-			rcte |= SAR_RCTE_RCQ;
-			break;
-		case ATM_AAL1:
-			rcte |= SAR_RCTE_OAM; /* Let SAR drop Video */
-			break;
-		case ATM_AAL34:
-			rcte |= SAR_RCTE_AAL34;
-			break;
-		case ATM_AAL5:
-			rcte |= SAR_RCTE_AAL5;
-			break;
-		default:
-			rcte |= SAR_RCTE_RCQ;
-			break;
-	}
-
-	if (qos->aal != ATM_AAL5)
-		rcte |= SAR_RCTE_FBP_1;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_2)
-		rcte |= SAR_RCTE_FBP_3;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_1)
-		rcte |= SAR_RCTE_FBP_2;
-	else if (qos->rxtp.max_sdu > SAR_FB_SIZE_0)
-		rcte |= SAR_RCTE_FBP_1;
-	else
-		rcte |= SAR_RCTE_FBP_01;
-
-	addr = card->rct_base + (vc->index << 2);
-
-	OPRINTK("%s: writing RCT at 0x%lx\n", card->name, addr);
-	write_sram(card, addr, rcte);
-
-	spin_lock_irqsave(&card->cmd_lock, flags);
-	writel(SAR_CMD_OPEN_CONNECTION | (addr << 2), SAR_REG_CMD);
-	waitfor_idle(card);
-	spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-	return 0;
-}
-
-static int
-idt77252_open(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc;
-	unsigned int index;
-	unsigned int inuse;
-	int error;
-	int vci = vcc->vci;
-	short vpi = vcc->vpi;
-
-	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
-		return 0;
-
-	if (vpi >= (1 << card->vpibits)) {
-		printk("%s: unsupported VPI: %d\n", card->name, vpi);
-		return -EINVAL;
-	}
-
-	if (vci >= (1 << card->vcibits)) {
-		printk("%s: unsupported VCI: %d\n", card->name, vci);
-		return -EINVAL;
-	}
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	mutex_lock(&card->mutex);
-
-	OPRINTK("%s: opening vpi.vci: %d.%d\n", card->name, vpi, vci);
-
-	switch (vcc->qos.aal) {
-	case ATM_AAL0:
-	case ATM_AAL1:
-	case ATM_AAL5:
-		break;
-	default:
-		printk("%s: Unsupported AAL: %d\n", card->name, vcc->qos.aal);
-		mutex_unlock(&card->mutex);
-		return -EPROTONOSUPPORT;
-	}
-
-	index = VPCI2VC(card, vpi, vci);
-	if (!card->vcs[index]) {
-		card->vcs[index] = kzalloc_obj(struct vc_map);
-		if (!card->vcs[index]) {
-			printk("%s: can't alloc vc in open()\n", card->name);
-			mutex_unlock(&card->mutex);
-			return -ENOMEM;
-		}
-		card->vcs[index]->card = card;
-		card->vcs[index]->index = index;
-
-		spin_lock_init(&card->vcs[index]->lock);
-	}
-	vc = card->vcs[index];
-
-	vcc->dev_data = vc;
-
-	IPRINTK("%s: idt77252_open: vc = %d (%d.%d) %s/%s (max RX SDU: %u)\n",
-	        card->name, vc->index, vcc->vpi, vcc->vci,
-	        vcc->qos.rxtp.traffic_class != ATM_NONE ? "rx" : "--",
-	        vcc->qos.txtp.traffic_class != ATM_NONE ? "tx" : "--",
-	        vcc->qos.rxtp.max_sdu);
-
-	inuse = 0;
-	if (vcc->qos.txtp.traffic_class != ATM_NONE &&
-	    test_bit(VCF_TX, &vc->flags))
-		inuse = 1;
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE &&
-	    test_bit(VCF_RX, &vc->flags))
-		inuse += 2;
-
-	if (inuse) {
-		printk("%s: %s vci already in use.\n", card->name,
-		       inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
-		mutex_unlock(&card->mutex);
-		return -EADDRINUSE;
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		error = idt77252_init_tx(card, vc, vcc, &vcc->qos);
-		if (error) {
-			mutex_unlock(&card->mutex);
-			return error;
-		}
-	}
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		error = idt77252_init_rx(card, vc, vcc, &vcc->qos);
-		if (error) {
-			mutex_unlock(&card->mutex);
-			return error;
-		}
-	}
-
-	set_bit(ATM_VF_READY, &vcc->flags);
-
-	mutex_unlock(&card->mutex);
-	return 0;
-}
-
-static void
-idt77252_close(struct atm_vcc *vcc)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	unsigned long flags;
-	unsigned long addr;
-	unsigned long timeout;
-
-	mutex_lock(&card->mutex);
-
-	IPRINTK("%s: idt77252_close: vc = %d (%d.%d)\n",
-		card->name, vc->index, vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-
-		spin_lock_irqsave(&vc->lock, flags);
-		clear_bit(VCF_RX, &vc->flags);
-		vc->rx_vcc = NULL;
-		spin_unlock_irqrestore(&vc->lock, flags);
-
-		if ((vcc->vci == 3) || (vcc->vci == 4))
-			goto done;
-
-		addr = card->rct_base + vc->index * SAR_SRAM_RCT_SIZE;
-
-		spin_lock_irqsave(&card->cmd_lock, flags);
-		writel(SAR_CMD_CLOSE_CONNECTION | (addr << 2), SAR_REG_CMD);
-		waitfor_idle(card);
-		spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-		if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
-			DPRINTK("%s: closing a VC with pending rx buffers.\n",
-				card->name);
-
-			recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
-		}
-	}
-
-done:
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-
-		spin_lock_irqsave(&vc->lock, flags);
-		clear_bit(VCF_TX, &vc->flags);
-		clear_bit(VCF_IDLE, &vc->flags);
-		clear_bit(VCF_RSV, &vc->flags);
-		vc->tx_vcc = NULL;
-
-		if (vc->estimator) {
-			timer_shutdown(&vc->estimator->timer);
-			kfree(vc->estimator);
-			vc->estimator = NULL;
-		}
-		spin_unlock_irqrestore(&vc->lock, flags);
-
-		timeout = 5 * 1000;
-		while (atomic_read(&vc->scq->used) > 0) {
-			timeout = msleep_interruptible(timeout);
-			if (!timeout) {
-				pr_warn("%s: SCQ drain timeout: %u used\n",
-					card->name, atomic_read(&vc->scq->used));
-				break;
-			}
-		}
-
-		writel(TCMDQ_HALT | vc->index, SAR_REG_TCMDQ);
-		clear_scd(card, vc->scq, vc->class);
-
-		if (vc->class == SCHED_CBR) {
-			clear_tst(card, vc);
-			card->tst_free += vc->ntste;
-			vc->ntste = 0;
-		}
-
-		card->scd2vc[vc->scd_index] = NULL;
-		free_scq(card, vc->scq);
-	}
-
-	mutex_unlock(&card->mutex);
-}
-
-static int
-idt77252_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)
-{
-	struct atm_dev *dev = vcc->dev;
-	struct idt77252_dev *card = dev->dev_data;
-	struct vc_map *vc = vcc->dev_data;
-	int error = 0;
-
-	mutex_lock(&card->mutex);
-
-	if (qos->txtp.traffic_class != ATM_NONE) {
-	    	if (!test_bit(VCF_TX, &vc->flags)) {
-			error = idt77252_init_tx(card, vc, vcc, qos);
-			if (error)
-				goto out;
-		} else {
-			switch (qos->txtp.traffic_class) {
-			case ATM_CBR:
-				error = idt77252_init_cbr(card, vc, vcc, qos);
-				if (error)
-					goto out;
-				break;
-
-			case ATM_UBR:
-				error = idt77252_init_ubr(card, vc, vcc, qos);
-				if (error)
-					goto out;
-
-				if (!test_bit(VCF_IDLE, &vc->flags)) {
-					writel(TCMDQ_LACR | (vc->lacr << 16) |
-					       vc->index, SAR_REG_TCMDQ);
-				}
-				break;
-
-			case ATM_VBR:
-			case ATM_ABR:
-				error = -EOPNOTSUPP;
-				goto out;
-			}
-		}
-	}
-
-	if ((qos->rxtp.traffic_class != ATM_NONE) &&
-	    !test_bit(VCF_RX, &vc->flags)) {
-		error = idt77252_init_rx(card, vc, vcc, qos);
-		if (error)
-			goto out;
-	}
-
-	memcpy(&vcc->qos, qos, sizeof(struct atm_qos));
-
-	set_bit(ATM_VF_HASQOS, &vcc->flags);
-
-out:
-	mutex_unlock(&card->mutex);
-	return error;
-}
-
-static int
-idt77252_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	int i, left;
-
-	left = (int) *pos;
-	if (!left--)
-		return sprintf(page, "IDT77252 Interrupts:\n");
-	if (!left--)
-		return sprintf(page, "TSIF:  %lu\n", card->irqstat[15]);
-	if (!left--)
-		return sprintf(page, "TXICP: %lu\n", card->irqstat[14]);
-	if (!left--)
-		return sprintf(page, "TSQF:  %lu\n", card->irqstat[12]);
-	if (!left--)
-		return sprintf(page, "TMROF: %lu\n", card->irqstat[11]);
-	if (!left--)
-		return sprintf(page, "PHYI:  %lu\n", card->irqstat[10]);
-	if (!left--)
-		return sprintf(page, "FBQ3A: %lu\n", card->irqstat[8]);
-	if (!left--)
-		return sprintf(page, "FBQ2A: %lu\n", card->irqstat[7]);
-	if (!left--)
-		return sprintf(page, "RSQF:  %lu\n", card->irqstat[6]);
-	if (!left--)
-		return sprintf(page, "EPDU:  %lu\n", card->irqstat[5]);
-	if (!left--)
-		return sprintf(page, "RAWCF: %lu\n", card->irqstat[4]);
-	if (!left--)
-		return sprintf(page, "FBQ1A: %lu\n", card->irqstat[3]);
-	if (!left--)
-		return sprintf(page, "FBQ0A: %lu\n", card->irqstat[2]);
-	if (!left--)
-		return sprintf(page, "RSQAF: %lu\n", card->irqstat[1]);
-	if (!left--)
-		return sprintf(page, "IDT77252 Transmit Connection Table:\n");
-
-	for (i = 0; i < card->tct_size; i++) {
-		unsigned long tct;
-		struct atm_vcc *vcc;
-		struct vc_map *vc;
-		char *p;
-
-		vc = card->vcs[i];
-		if (!vc)
-			continue;
-
-		vcc = NULL;
-		if (vc->tx_vcc)
-			vcc = vc->tx_vcc;
-		if (!vcc)
-			continue;
-		if (left--)
-			continue;
-
-		p = page;
-		p += sprintf(p, "  %4u: %u.%u: ", i, vcc->vpi, vcc->vci);
-		tct = (unsigned long) (card->tct_base + i * SAR_SRAM_TCT_SIZE);
-
-		for (i = 0; i < 8; i++)
-			p += sprintf(p, " %08x", read_sram(card, tct + i));
-		p += sprintf(p, "\n");
-		return p - page;
-	}
-	return 0;
-}
-
-/*****************************************************************************/
-/*                                                                           */
-/* Interrupt handler                                                         */
-/*                                                                           */
-/*****************************************************************************/
-
-static void
-idt77252_collect_stat(struct idt77252_dev *card)
-{
-	(void) readl(SAR_REG_CDC);
-	(void) readl(SAR_REG_VPEC);
-	(void) readl(SAR_REG_ICC);
-
-}
-
-static irqreturn_t
-idt77252_interrupt(int irq, void *dev_id)
-{
-	struct idt77252_dev *card = dev_id;
-	u32 stat;
-
-	stat = readl(SAR_REG_STAT) & 0xffff;
-	if (!stat)	/* no interrupt for us */
-		return IRQ_NONE;
-
-	if (test_and_set_bit(IDT77252_BIT_INTERRUPT, &card->flags)) {
-		printk("%s: Re-entering irq_handler()\n", card->name);
-		goto out;
-	}
-
-	writel(stat, SAR_REG_STAT);	/* reset interrupt */
-
-	if (stat & SAR_STAT_TSIF) {	/* entry written to TSQ  */
-		INTPRINTK("%s: TSIF\n", card->name);
-		card->irqstat[15]++;
-		idt77252_tx(card);
-	}
-	if (stat & SAR_STAT_TXICP) {	/* Incomplete CS-PDU has  */
-		INTPRINTK("%s: TXICP\n", card->name);
-		card->irqstat[14]++;
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-		idt77252_tx_dump(card);
-#endif
-	}
-	if (stat & SAR_STAT_TSQF) {	/* TSQ 7/8 full           */
-		INTPRINTK("%s: TSQF\n", card->name);
-		card->irqstat[12]++;
-		idt77252_tx(card);
-	}
-	if (stat & SAR_STAT_TMROF) {	/* Timer overflow         */
-		INTPRINTK("%s: TMROF\n", card->name);
-		card->irqstat[11]++;
-		idt77252_collect_stat(card);
-	}
-
-	if (stat & SAR_STAT_EPDU) {	/* Got complete CS-PDU    */
-		INTPRINTK("%s: EPDU\n", card->name);
-		card->irqstat[5]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RSQAF) {	/* RSQ is 7/8 full        */
-		INTPRINTK("%s: RSQAF\n", card->name);
-		card->irqstat[1]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RSQF) {	/* RSQ is full            */
-		INTPRINTK("%s: RSQF\n", card->name);
-		card->irqstat[6]++;
-		idt77252_rx(card);
-	}
-	if (stat & SAR_STAT_RAWCF) {	/* Raw cell received      */
-		INTPRINTK("%s: RAWCF\n", card->name);
-		card->irqstat[4]++;
-		idt77252_rx_raw(card);
-	}
-
-	if (stat & SAR_STAT_PHYI) {	/* PHY device interrupt   */
-		INTPRINTK("%s: PHYI", card->name);
-		card->irqstat[10]++;
-		if (card->atmdev->phy && card->atmdev->phy->interrupt)
-			card->atmdev->phy->interrupt(card->atmdev);
-	}
-
-	if (stat & (SAR_STAT_FBQ0A | SAR_STAT_FBQ1A |
-		    SAR_STAT_FBQ2A | SAR_STAT_FBQ3A)) {
-
-		writel(readl(SAR_REG_CFG) & ~(SAR_CFG_FBIE), SAR_REG_CFG);
-
-		INTPRINTK("%s: FBQA: %04x\n", card->name, stat);
-
-		if (stat & SAR_STAT_FBQ0A)
-			card->irqstat[2]++;
-		if (stat & SAR_STAT_FBQ1A)
-			card->irqstat[3]++;
-		if (stat & SAR_STAT_FBQ2A)
-			card->irqstat[7]++;
-		if (stat & SAR_STAT_FBQ3A)
-			card->irqstat[8]++;
-
-		schedule_work(&card->tqueue);
-	}
-
-out:
-	clear_bit(IDT77252_BIT_INTERRUPT, &card->flags);
-	return IRQ_HANDLED;
-}
-
-static void
-idt77252_softint(struct work_struct *work)
-{
-	struct idt77252_dev *card =
-		container_of(work, struct idt77252_dev, tqueue);
-	u32 stat;
-	int done;
-
-	for (done = 1; ; done = 1) {
-		stat = readl(SAR_REG_STAT) >> 16;
-
-		if ((stat & 0x0f) < SAR_FBQ0_HIGH) {
-			add_rx_skb(card, 0, SAR_FB_SIZE_0, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ1_HIGH) {
-			add_rx_skb(card, 1, SAR_FB_SIZE_1, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ2_HIGH) {
-			add_rx_skb(card, 2, SAR_FB_SIZE_2, 32);
-			done = 0;
-		}
-
-		stat >>= 4;
-		if ((stat & 0x0f) < SAR_FBQ3_HIGH) {
-			add_rx_skb(card, 3, SAR_FB_SIZE_3, 32);
-			done = 0;
-		}
-
-		if (done)
-			break;
-	}
-
-	writel(readl(SAR_REG_CFG) | SAR_CFG_FBIE, SAR_REG_CFG);
-}
-
-
-static int
-open_card_oam(struct idt77252_dev *card)
-{
-	unsigned long flags;
-	unsigned long addr;
-	struct vc_map *vc;
-	int vpi, vci;
-	int index;
-	u32 rcte;
-
-	for (vpi = 0; vpi < (1 << card->vpibits); vpi++) {
-		for (vci = 3; vci < 5; vci++) {
-			index = VPCI2VC(card, vpi, vci);
-
-			vc = kzalloc_obj(struct vc_map);
-			if (!vc) {
-				printk("%s: can't alloc vc\n", card->name);
-				return -ENOMEM;
-			}
-			vc->index = index;
-			card->vcs[index] = vc;
-
-			flush_rx_pool(card, &vc->rcv.rx_pool);
-
-			rcte = SAR_RCTE_CONNECTOPEN |
-			       SAR_RCTE_RAWCELLINTEN |
-			       SAR_RCTE_RCQ |
-			       SAR_RCTE_FBP_1;
-
-			addr = card->rct_base + (vc->index << 2);
-			write_sram(card, addr, rcte);
-
-			spin_lock_irqsave(&card->cmd_lock, flags);
-			writel(SAR_CMD_OPEN_CONNECTION | (addr << 2),
-			       SAR_REG_CMD);
-			waitfor_idle(card);
-			spin_unlock_irqrestore(&card->cmd_lock, flags);
-		}
-	}
-
-	return 0;
-}
-
-static void
-close_card_oam(struct idt77252_dev *card)
-{
-	unsigned long flags;
-	unsigned long addr;
-	struct vc_map *vc;
-	int vpi, vci;
-	int index;
-
-	for (vpi = 0; vpi < (1 << card->vpibits); vpi++) {
-		for (vci = 3; vci < 5; vci++) {
-			index = VPCI2VC(card, vpi, vci);
-			vc = card->vcs[index];
-
-			addr = card->rct_base + vc->index * SAR_SRAM_RCT_SIZE;
-
-			spin_lock_irqsave(&card->cmd_lock, flags);
-			writel(SAR_CMD_CLOSE_CONNECTION | (addr << 2),
-			       SAR_REG_CMD);
-			waitfor_idle(card);
-			spin_unlock_irqrestore(&card->cmd_lock, flags);
-
-			if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
-				DPRINTK("%s: closing a VC "
-					"with pending rx buffers.\n",
-					card->name);
-
-				recycle_rx_pool_skb(card, &vc->rcv.rx_pool);
-			}
-			kfree(vc);
-		}
-	}
-}
-
-static int
-open_card_ubr0(struct idt77252_dev *card)
-{
-	struct vc_map *vc;
-
-	vc = kzalloc_obj(struct vc_map);
-	if (!vc) {
-		printk("%s: can't alloc vc\n", card->name);
-		return -ENOMEM;
-	}
-	card->vcs[0] = vc;
-	vc->class = SCHED_UBR0;
-
-	vc->scq = alloc_scq(card, vc->class);
-	if (!vc->scq) {
-		printk("%s: can't get SCQ.\n", card->name);
-		kfree(card->vcs[0]);
-		card->vcs[0] = NULL;
-		return -ENOMEM;
-	}
-
-	card->scd2vc[0] = vc;
-	vc->scd_index = 0;
-	vc->scq->scd = card->scd_base;
-
-	fill_scd(card, vc->scq, vc->class);
-
-	write_sram(card, card->tct_base + 0, TCT_UBR | card->scd_base);
-	write_sram(card, card->tct_base + 1, 0);
-	write_sram(card, card->tct_base + 2, 0);
-	write_sram(card, card->tct_base + 3, 0);
-	write_sram(card, card->tct_base + 4, 0);
-	write_sram(card, card->tct_base + 5, 0);
-	write_sram(card, card->tct_base + 6, 0);
-	write_sram(card, card->tct_base + 7, TCT_FLAG_UBR);
-
-	clear_bit(VCF_IDLE, &vc->flags);
-	writel(TCMDQ_START | 0, SAR_REG_TCMDQ);
-	return 0;
-}
-
-static void
-close_card_ubr0(struct idt77252_dev *card)
-{
-	struct vc_map *vc = card->vcs[0];
-
-	free_scq(card, vc->scq);
-	kfree(vc);
-}
-
-static int
-idt77252_dev_open(struct idt77252_dev *card)
-{
-	u32 conf;
-
-	if (!test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("%s: SAR not yet initialized.\n", card->name);
-		return -1;
-	}
-
-	conf = SAR_CFG_RXPTH|	/* enable receive path                  */
-	    SAR_RX_DELAY |	/* interrupt on complete PDU		*/
-	    SAR_CFG_RAWIE |	/* interrupt enable on raw cells        */
-	    SAR_CFG_RQFIE |	/* interrupt on RSQ almost full         */
-	    SAR_CFG_TMOIE |	/* interrupt on timer overflow          */
-	    SAR_CFG_FBIE |	/* interrupt on low free buffers        */
-	    SAR_CFG_TXEN |	/* transmit operation enable            */
-	    SAR_CFG_TXINT |	/* interrupt on transmit status         */
-	    SAR_CFG_TXUIE |	/* interrupt on transmit underrun       */
-	    SAR_CFG_TXSFI |	/* interrupt on TSQ almost full         */
-	    SAR_CFG_PHYIE	/* enable PHY interrupts		*/
-	    ;
-
-#ifdef CONFIG_ATM_IDT77252_RCV_ALL
-	/* Test RAW cell receive. */
-	conf |= SAR_CFG_VPECA;
-#endif
-
-	writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
-
-	if (open_card_oam(card)) {
-		printk("%s: Error initializing OAM.\n", card->name);
-		return -1;
-	}
-
-	if (open_card_ubr0(card)) {
-		printk("%s: Error initializing UBR0.\n", card->name);
-		return -1;
-	}
-
-	IPRINTK("%s: opened IDT77252 ABR SAR.\n", card->name);
-	return 0;
-}
-
-static void idt77252_dev_close(struct atm_dev *dev)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	u32 conf;
-
-	close_card_ubr0(card);
-	close_card_oam(card);
-
-	conf = SAR_CFG_RXPTH |	/* enable receive path           */
-	    SAR_RX_DELAY |	/* interrupt on complete PDU     */
-	    SAR_CFG_RAWIE |	/* interrupt enable on raw cells */
-	    SAR_CFG_RQFIE |	/* interrupt on RSQ almost full  */
-	    SAR_CFG_TMOIE |	/* interrupt on timer overflow   */
-	    SAR_CFG_FBIE |	/* interrupt on low free buffers */
-	    SAR_CFG_TXEN |	/* transmit operation enable     */
-	    SAR_CFG_TXINT |	/* interrupt on transmit status  */
-	    SAR_CFG_TXUIE |	/* interrupt on xmit underrun    */
-	    SAR_CFG_TXSFI	/* interrupt on TSQ almost full  */
-	    ;
-
-	writel(readl(SAR_REG_CFG) & ~(conf), SAR_REG_CFG);
-
-	DIPRINTK("%s: closed IDT77252 ABR SAR.\n", card->name);
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* Initialisation and Deinitialization of IDT77252                           */
-/*                                                                           */
-/*****************************************************************************/
-
-
-static void
-deinit_card(struct idt77252_dev *card)
-{
-	struct sk_buff *skb;
-	int i, j;
-
-	if (!test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("%s: SAR not yet initialized.\n", card->name);
-		return;
-	}
-	DIPRINTK("idt77252: deinitialize card %u\n", card->index);
-
-	writel(0, SAR_REG_CFG);
-
-	if (card->atmdev)
-		atm_dev_deregister(card->atmdev);
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < FBQ_SIZE; j++) {
-			skb = card->sbpool[i].skb[j];
-			if (skb) {
-				dma_unmap_single(&card->pcidev->dev,
-						 IDT77252_PRV_PADDR(skb),
-						 (skb_end_pointer(skb) -
-						  skb->data),
-						 DMA_FROM_DEVICE);
-				card->sbpool[i].skb[j] = NULL;
-				dev_kfree_skb(skb);
-			}
-		}
-	}
-
-	vfree(card->soft_tst);
-
-	vfree(card->scd2vc);
-
-	vfree(card->vcs);
-
-	if (card->raw_cell_hnd) {
-		dma_free_coherent(&card->pcidev->dev, 2 * sizeof(u32),
-				  card->raw_cell_hnd, card->raw_cell_paddr);
-	}
-
-	if (card->rsq.base) {
-		DIPRINTK("%s: Release RSQ ...\n", card->name);
-		deinit_rsq(card);
-	}
-
-	if (card->tsq.base) {
-		DIPRINTK("%s: Release TSQ ...\n", card->name);
-		deinit_tsq(card);
-	}
-
-	DIPRINTK("idt77252: Release IRQ.\n");
-	free_irq(card->pcidev->irq, card);
-
-	for (i = 0; i < 4; i++) {
-		if (card->fbq[i])
-			iounmap(card->fbq[i]);
-	}
-
-	if (card->membase)
-		iounmap(card->membase);
-
-	clear_bit(IDT77252_BIT_INIT, &card->flags);
-	DIPRINTK("%s: Card deinitialized.\n", card->name);
-}
-
-
-static void init_sram(struct idt77252_dev *card)
-{
-	int i;
-
-	for (i = 0; i < card->sramsize; i += 4)
-		write_sram(card, (i >> 2), 0);
-
-	/* set SRAM layout for THIS card */
-	if (card->sramsize == (512 * 1024)) {
-		card->tct_base = SAR_SRAM_TCT_128_BASE;
-		card->tct_size = (SAR_SRAM_TCT_128_TOP - card->tct_base + 1)
-		    / SAR_SRAM_TCT_SIZE;
-		card->rct_base = SAR_SRAM_RCT_128_BASE;
-		card->rct_size = (SAR_SRAM_RCT_128_TOP - card->rct_base + 1)
-		    / SAR_SRAM_RCT_SIZE;
-		card->rt_base = SAR_SRAM_RT_128_BASE;
-		card->scd_base = SAR_SRAM_SCD_128_BASE;
-		card->scd_size = (SAR_SRAM_SCD_128_TOP - card->scd_base + 1)
-		    / SAR_SRAM_SCD_SIZE;
-		card->tst[0] = SAR_SRAM_TST1_128_BASE;
-		card->tst[1] = SAR_SRAM_TST2_128_BASE;
-		card->tst_size = SAR_SRAM_TST1_128_TOP - card->tst[0] + 1;
-		card->abrst_base = SAR_SRAM_ABRSTD_128_BASE;
-		card->abrst_size = SAR_ABRSTD_SIZE_8K;
-		card->fifo_base = SAR_SRAM_FIFO_128_BASE;
-		card->fifo_size = SAR_RXFD_SIZE_32K;
-	} else {
-		card->tct_base = SAR_SRAM_TCT_32_BASE;
-		card->tct_size = (SAR_SRAM_TCT_32_TOP - card->tct_base + 1)
-		    / SAR_SRAM_TCT_SIZE;
-		card->rct_base = SAR_SRAM_RCT_32_BASE;
-		card->rct_size = (SAR_SRAM_RCT_32_TOP - card->rct_base + 1)
-		    / SAR_SRAM_RCT_SIZE;
-		card->rt_base = SAR_SRAM_RT_32_BASE;
-		card->scd_base = SAR_SRAM_SCD_32_BASE;
-		card->scd_size = (SAR_SRAM_SCD_32_TOP - card->scd_base + 1)
-		    / SAR_SRAM_SCD_SIZE;
-		card->tst[0] = SAR_SRAM_TST1_32_BASE;
-		card->tst[1] = SAR_SRAM_TST2_32_BASE;
-		card->tst_size = (SAR_SRAM_TST1_32_TOP - card->tst[0] + 1);
-		card->abrst_base = SAR_SRAM_ABRSTD_32_BASE;
-		card->abrst_size = SAR_ABRSTD_SIZE_1K;
-		card->fifo_base = SAR_SRAM_FIFO_32_BASE;
-		card->fifo_size = SAR_RXFD_SIZE_4K;
-	}
-
-	/* Initialize TCT */
-	for (i = 0; i < card->tct_size; i++) {
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 0, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 1, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 2, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 3, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 4, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 5, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 6, 0);
-		write_sram(card, i * SAR_SRAM_TCT_SIZE + 7, 0);
-	}
-
-	/* Initialize RCT */
-	for (i = 0; i < card->rct_size; i++) {
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE,
-				    (u32) SAR_RCTE_RAWCELLINTEN);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 1,
-				    (u32) 0);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 2,
-				    (u32) 0);
-		write_sram(card, card->rct_base + i * SAR_SRAM_RCT_SIZE + 3,
-				    (u32) 0xffffffff);
-	}
-
-	writel((SAR_FBQ0_LOW << 28) | (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0);
-	writel((SAR_FBQ1_LOW << 28) | (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1);
-	writel((SAR_FBQ2_LOW << 28) | (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2);
-	writel((SAR_FBQ3_LOW << 28) | (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3);
-
-	/* Initialize rate table  */
-	for (i = 0; i < 256; i++) {
-		write_sram(card, card->rt_base + i, log_to_rate[i]);
-	}
-
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp  = rate_to_log[(i << 2) + 0] << 0;
-		tmp |= rate_to_log[(i << 2) + 1] << 8;
-		tmp |= rate_to_log[(i << 2) + 2] << 16;
-		tmp |= rate_to_log[(i << 2) + 3] << 24;
-		write_sram(card, card->rt_base + 256 + i, tmp);
-	}
-
-#if 0 /* Fill RDF and AIR tables. */
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp = RDF[0][(i << 1) + 0] << 16;
-		tmp |= RDF[0][(i << 1) + 1] << 0;
-		write_sram(card, card->rt_base + 512 + i, tmp);
-	}
-
-	for (i = 0; i < 128; i++) {
-		unsigned int tmp;
-
-		tmp = AIR[0][(i << 1) + 0] << 16;
-		tmp |= AIR[0][(i << 1) + 1] << 0;
-		write_sram(card, card->rt_base + 640 + i, tmp);
-	}
-#endif
-
-	IPRINTK("%s: initialize rate table ...\n", card->name);
-	writel(card->rt_base << 2, SAR_REG_RTBL);
-
-	/* Initialize TSTs */
-	IPRINTK("%s: initialize TST ...\n", card->name);
-	card->tst_free = card->tst_size - 2;	/* last two are jumps */
-
-	for (i = card->tst[0]; i < card->tst[0] + card->tst_size - 2; i++)
-		write_sram(card, i, TSTE_OPC_VAR);
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[0] << 2));
-	idt77252_sram_write_errors = 1;
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[1] << 2));
-	idt77252_sram_write_errors = 0;
-	for (i = card->tst[1]; i < card->tst[1] + card->tst_size - 2; i++)
-		write_sram(card, i, TSTE_OPC_VAR);
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[1] << 2));
-	idt77252_sram_write_errors = 1;
-	write_sram(card, i++, TSTE_OPC_JMP | (card->tst[0] << 2));
-	idt77252_sram_write_errors = 0;
-
-	card->tst_index = 0;
-	writel(card->tst[0] << 2, SAR_REG_TSTB);
-
-	/* Initialize ABRSTD and Receive FIFO */
-	IPRINTK("%s: initialize ABRSTD ...\n", card->name);
-	writel(card->abrst_size | (card->abrst_base << 2),
-	       SAR_REG_ABRSTD);
-
-	IPRINTK("%s: initialize receive fifo ...\n", card->name);
-	writel(card->fifo_size | (card->fifo_base << 2),
-	       SAR_REG_RXFD);
-
-	IPRINTK("%s: SRAM initialization complete.\n", card->name);
-}
-
-static int init_card(struct atm_dev *dev)
-{
-	struct idt77252_dev *card = dev->dev_data;
-	struct pci_dev *pcidev = card->pcidev;
-	unsigned long tmpl, modl;
-	unsigned int linkrate, rsvdcr;
-	unsigned int tst_entries;
-	struct net_device *tmp;
-	char tname[10];
-
-	u32 size;
-	u_char pci_byte;
-	u32 conf;
-	int i, k;
-
-	if (test_bit(IDT77252_BIT_INIT, &card->flags)) {
-		printk("Error: SAR already initialized.\n");
-		return -1;
-	}
-
-/*****************************************************************/
-/*   P C I   C O N F I G U R A T I O N                           */
-/*****************************************************************/
-
-	/* Set PCI Retry-Timeout and TRDY timeout */
-	IPRINTK("%s: Checking PCI retries.\n", card->name);
-	if (pci_read_config_byte(pcidev, 0x40, &pci_byte) != 0) {
-		printk("%s: can't read PCI retry timeout.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (pci_byte != 0) {
-		IPRINTK("%s: PCI retry timeout: %d, set to 0.\n",
-			card->name, pci_byte);
-		if (pci_write_config_byte(pcidev, 0x40, 0) != 0) {
-			printk("%s: can't set PCI retry timeout.\n",
-			       card->name);
-			deinit_card(card);
-			return -1;
-		}
-	}
-	IPRINTK("%s: Checking PCI TRDY.\n", card->name);
-	if (pci_read_config_byte(pcidev, 0x41, &pci_byte) != 0) {
-		printk("%s: can't read PCI TRDY timeout.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (pci_byte != 0) {
-		IPRINTK("%s: PCI TRDY timeout: %d, set to 0.\n",
-		        card->name, pci_byte);
-		if (pci_write_config_byte(pcidev, 0x41, 0) != 0) {
-			printk("%s: can't set PCI TRDY timeout.\n", card->name);
-			deinit_card(card);
-			return -1;
-		}
-	}
-	/* Reset Timer register */
-	if (readl(SAR_REG_STAT) & SAR_STAT_TMROF) {
-		printk("%s: resetting timer overflow.\n", card->name);
-		writel(SAR_STAT_TMROF, SAR_REG_STAT);
-	}
-	IPRINTK("%s: Request IRQ ... ", card->name);
-	if (request_irq(pcidev->irq, idt77252_interrupt, IRQF_SHARED,
-			card->name, card) != 0) {
-		printk("%s: can't allocate IRQ.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	IPRINTK("got %d.\n", pcidev->irq);
-
-/*****************************************************************/
-/*   C H E C K   A N D   I N I T   S R A M                       */
-/*****************************************************************/
-
-	IPRINTK("%s: Initializing SRAM\n", card->name);
-
-	/* preset size of connecton table, so that init_sram() knows about it */
-	conf =	SAR_CFG_TX_FIFO_SIZE_9 |	/* Use maximum fifo size */
-		SAR_CFG_RXSTQ_SIZE_8k |		/* Receive Status Queue is 8k */
-		SAR_CFG_IDLE_CLP |		/* Set CLP on idle cells */
-#ifndef ATM_IDT77252_SEND_IDLE
-		SAR_CFG_NO_IDLE |		/* Do not send idle cells */
-#endif
-		0;
-
-	if (card->sramsize == (512 * 1024))
-		conf |= SAR_CFG_CNTBL_1k;
-	else
-		conf |= SAR_CFG_CNTBL_512;
-
-	switch (vpibits) {
-	case 0:
-		conf |= SAR_CFG_VPVCS_0;
-		break;
-	default:
-	case 1:
-		conf |= SAR_CFG_VPVCS_1;
-		break;
-	case 2:
-		conf |= SAR_CFG_VPVCS_2;
-		break;
-	case 8:
-		conf |= SAR_CFG_VPVCS_8;
-		break;
-	}
-
-	writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG);
-
-	init_sram(card);
-
-/********************************************************************/
-/*  A L L O C   R A M   A N D   S E T   V A R I O U S   T H I N G S */
-/********************************************************************/
-	/* Initialize TSQ */
-	if (0 != init_tsq(card)) {
-		deinit_card(card);
-		return -1;
-	}
-	/* Initialize RSQ */
-	if (0 != init_rsq(card)) {
-		deinit_card(card);
-		return -1;
-	}
-
-	card->vpibits = vpibits;
-	if (card->sramsize == (512 * 1024)) {
-		card->vcibits = 10 - card->vpibits;
-	} else {
-		card->vcibits = 9 - card->vpibits;
-	}
-
-	card->vcimask = 0;
-	for (k = 0, i = 1; k < card->vcibits; k++) {
-		card->vcimask |= i;
-		i <<= 1;
-	}
-
-	IPRINTK("%s: Setting VPI/VCI mask to zero.\n", card->name);
-	writel(0, SAR_REG_VPM);
-
-	/* Little Endian Order   */
-	writel(0, SAR_REG_GP);
-
-	/* Initialize RAW Cell Handle Register  */
-	card->raw_cell_hnd = dma_alloc_coherent(&card->pcidev->dev,
-						2 * sizeof(u32),
-						&card->raw_cell_paddr,
-						GFP_KERNEL);
-	if (!card->raw_cell_hnd) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	writel(card->raw_cell_paddr, SAR_REG_RAWHND);
-	IPRINTK("%s: raw cell handle is at 0x%p.\n", card->name,
-		card->raw_cell_hnd);
-
-	size = sizeof(struct vc_map *) * card->tct_size;
-	IPRINTK("%s: allocate %d byte for VC map.\n", card->name, size);
-	card->vcs = vzalloc(size);
-	if (!card->vcs) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-	size = sizeof(struct vc_map *) * card->scd_size;
-	IPRINTK("%s: allocate %d byte for SCD to VC mapping.\n",
-	        card->name, size);
-	card->scd2vc = vzalloc(size);
-	if (!card->scd2vc) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-	size = sizeof(struct tst_info) * (card->tst_size - 2);
-	IPRINTK("%s: allocate %d byte for TST to VC mapping.\n",
-		card->name, size);
-	card->soft_tst = vmalloc(size);
-	if (!card->soft_tst) {
-		printk("%s: memory allocation failure.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	for (i = 0; i < card->tst_size - 2; i++) {
-		card->soft_tst[i].tste = TSTE_OPC_VAR;
-		card->soft_tst[i].vc = NULL;
-	}
-
-	if (dev->phy == NULL) {
-		printk("%s: No LT device defined.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (dev->phy->ioctl == NULL) {
-		printk("%s: LT had no IOCTL function defined.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-
-#ifdef	CONFIG_ATM_IDT77252_USE_SUNI
-	/*
-	 * this is a jhs hack to get around special functionality in the
-	 * phy driver for the atecom hardware; the functionality doesn't
-	 * exist in the linux atm suni driver
-	 *
-	 * it isn't the right way to do things, but as the guy from NIST
-	 * said, talking about their measurement of the fine structure
-	 * constant, "it's good enough for government work."
-	 */
-	linkrate = 149760000;
-#endif
-
-	card->link_pcr = (linkrate / 8 / 53);
-	printk("%s: Linkrate on ATM line : %u bit/s, %u cell/s.\n",
-	       card->name, linkrate, card->link_pcr);
-
-#ifdef ATM_IDT77252_SEND_IDLE
-	card->utopia_pcr = card->link_pcr;
-#else
-	card->utopia_pcr = (160000000 / 8 / 54);
-#endif
-
-	rsvdcr = 0;
-	if (card->utopia_pcr > card->link_pcr)
-		rsvdcr = card->utopia_pcr - card->link_pcr;
-
-	tmpl = (unsigned long) rsvdcr * ((unsigned long) card->tst_size - 2);
-	modl = tmpl % (unsigned long)card->utopia_pcr;
-	tst_entries = (int) (tmpl / (unsigned long)card->utopia_pcr);
-	if (modl)
-		tst_entries++;
-	card->tst_free -= tst_entries;
-	fill_tst(card, NULL, tst_entries, TSTE_OPC_NULL);
-
-#ifdef HAVE_EEPROM
-	idt77252_eeprom_init(card);
-	printk("%s: EEPROM: %02x:", card->name,
-		idt77252_eeprom_read_status(card));
-
-	for (i = 0; i < 0x80; i++) {
-		printk(" %02x", 
-		idt77252_eeprom_read_byte(card, i)
-		);
-	}
-	printk("\n");
-#endif /* HAVE_EEPROM */
-
-	/*
-	 * XXX: <hack>
-	 */
-	sprintf(tname, "eth%d", card->index);
-	tmp = dev_get_by_name(&init_net, tname);	/* jhs: was "tmp = dev_get(tname);" */
-	if (tmp) {
-		memcpy(card->atmdev->esi, tmp->dev_addr, 6);
-		dev_put(tmp);
-		printk("%s: ESI %pM\n", card->name, card->atmdev->esi);
-	}
-	/*
-	 * XXX: </hack>
-	 */
-
-	/* Set Maximum Deficit Count for now. */
-	writel(0xffff, SAR_REG_MDFCT);
-
-	set_bit(IDT77252_BIT_INIT, &card->flags);
-
-	XPRINTK("%s: IDT77252 ABR SAR initialization complete.\n", card->name);
-	return 0;
-}
-
-
-/*****************************************************************************/
-/*                                                                           */
-/* Probing of IDT77252 ABR SAR                                               */
-/*                                                                           */
-/*****************************************************************************/
-
-
-static int idt77252_preset(struct idt77252_dev *card)
-{
-	u16 pci_command;
-
-/*****************************************************************/
-/*   P C I   C O N F I G U R A T I O N                           */
-/*****************************************************************/
-
-	XPRINTK("%s: Enable PCI master and memory access for SAR.\n",
-		card->name);
-	if (pci_read_config_word(card->pcidev, PCI_COMMAND, &pci_command)) {
-		printk("%s: can't read PCI_COMMAND.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-	if (!(pci_command & PCI_COMMAND_IO)) {
-		printk("%s: PCI_COMMAND: %04x (?)\n",
-		       card->name, pci_command);
-		deinit_card(card);
-		return (-1);
-	}
-	pci_command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-	if (pci_write_config_word(card->pcidev, PCI_COMMAND, pci_command)) {
-		printk("%s: can't write PCI_COMMAND.\n", card->name);
-		deinit_card(card);
-		return -1;
-	}
-/*****************************************************************/
-/*   G E N E R I C   R E S E T                                   */
-/*****************************************************************/
-
-	/* Software reset */
-	writel(SAR_CFG_SWRST, SAR_REG_CFG);
-	mdelay(1);
-	writel(0, SAR_REG_CFG);
-
-	IPRINTK("%s: Software resetted.\n", card->name);
-	return 0;
-}
-
-
-static unsigned long probe_sram(struct idt77252_dev *card)
-{
-	u32 data, addr;
-
-	writel(0, SAR_REG_DR0);
-	writel(SAR_CMD_WRITE_SRAM | (0 << 2), SAR_REG_CMD);
-
-	for (addr = 0x4000; addr < 0x80000; addr += 0x4000) {
-		writel(ATM_POISON, SAR_REG_DR0);
-		writel(SAR_CMD_WRITE_SRAM | (addr << 2), SAR_REG_CMD);
-
-		writel(SAR_CMD_READ_SRAM | (0 << 2), SAR_REG_CMD);
-		data = readl(SAR_REG_DR0);
-
-		if (data != 0)
-			break;
-	}
-
-	return addr * sizeof(u32);
-}
-
-static int idt77252_init_one(struct pci_dev *pcidev,
-			     const struct pci_device_id *id)
-{
-	static struct idt77252_dev **last = &idt77252_chain;
-	static int index = 0;
-
-	unsigned long membase, srambase;
-	struct idt77252_dev *card;
-	struct atm_dev *dev;
-	int i, err;
-
-
-	if ((err = pci_enable_device(pcidev))) {
-		printk("idt77252: can't enable PCI device at %s\n", pci_name(pcidev));
-		return err;
-	}
-
-	if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) {
-		printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev));
-		goto err_out_disable_pdev;
-	}
-
-	card = kzalloc_obj(struct idt77252_dev);
-	if (!card) {
-		printk("idt77252-%d: can't allocate private data\n", index);
-		err = -ENOMEM;
-		goto err_out_disable_pdev;
-	}
-	card->revision = pcidev->revision;
-	card->index = index;
-	card->pcidev = pcidev;
-	sprintf(card->name, "idt77252-%d", card->index);
-
-	INIT_WORK(&card->tqueue, idt77252_softint);
-
-	membase = pci_resource_start(pcidev, 1);
-	srambase = pci_resource_start(pcidev, 2);
-
-	mutex_init(&card->mutex);
-	spin_lock_init(&card->cmd_lock);
-	spin_lock_init(&card->tst_lock);
-
-	timer_setup(&card->tst_timer, tst_timer, 0);
-
-	/* Do the I/O remapping... */
-	card->membase = ioremap(membase, 1024);
-	if (!card->membase) {
-		printk("%s: can't ioremap() membase\n", card->name);
-		err = -EIO;
-		goto err_out_free_card;
-	}
-
-	if (idt77252_preset(card)) {
-		printk("%s: preset failed\n", card->name);
-		err = -EIO;
-		goto err_out_iounmap;
-	}
-
-	dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1,
-			       NULL);
-	if (!dev) {
-		printk("%s: can't register atm device\n", card->name);
-		err = -EIO;
-		goto err_out_iounmap;
-	}
-	dev->dev_data = card;
-	card->atmdev = dev;
-
-#ifdef	CONFIG_ATM_IDT77252_USE_SUNI
-	suni_init(dev);
-	if (!dev->phy) {
-		printk("%s: can't init SUNI\n", card->name);
-		err = -EIO;
-		goto err_out_deinit_card;
-	}
-#endif	/* CONFIG_ATM_IDT77252_USE_SUNI */
-
-	card->sramsize = probe_sram(card);
-
-	for (i = 0; i < 4; i++) {
-		card->fbq[i] = ioremap(srambase | 0x200000 | (i << 18), 4);
-		if (!card->fbq[i]) {
-			printk("%s: can't ioremap() FBQ%d\n", card->name, i);
-			err = -EIO;
-			goto err_out_deinit_card;
-		}
-	}
-
-	printk("%s: ABR SAR (Rev %c): MEM %08lx SRAM %08lx [%u KB]\n",
-	       card->name, ((card->revision > 1) && (card->revision < 25)) ?
-	       'A' + card->revision - 1 : '?', membase, srambase,
-	       card->sramsize / 1024);
-
-	if (init_card(dev)) {
-		printk("%s: init_card failed\n", card->name);
-		err = -EIO;
-		goto err_out_deinit_card;
-	}
-
-	dev->ci_range.vpi_bits = card->vpibits;
-	dev->ci_range.vci_bits = card->vcibits;
-	dev->link_rate = card->link_pcr;
-
-	if (dev->phy->start)
-		dev->phy->start(dev);
-
-	if (idt77252_dev_open(card)) {
-		printk("%s: dev_open failed\n", card->name);
-		err = -EIO;
-		goto err_out_stop;
-	}
-
-	*last = card;
-	last = &card->next;
-	index++;
-
-	return 0;
-
-err_out_stop:
-	if (dev->phy->stop)
-		dev->phy->stop(dev);
-
-err_out_deinit_card:
-	deinit_card(card);
-
-err_out_iounmap:
-	iounmap(card->membase);
-
-err_out_free_card:
-	kfree(card);
-
-err_out_disable_pdev:
-	pci_disable_device(pcidev);
-	return err;
-}
-
-static const struct pci_device_id idt77252_pci_tbl[] =
-{
-	{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 },
-	{ 0, }
-};
-
-MODULE_DEVICE_TABLE(pci, idt77252_pci_tbl);
-
-static struct pci_driver idt77252_driver = {
-	.name		= "idt77252",
-	.id_table	= idt77252_pci_tbl,
-	.probe		= idt77252_init_one,
-};
-
-static int __init idt77252_init(void)
-{
-	struct sk_buff *skb;
-
-	printk("%s: at %p\n", __func__, idt77252_init);
-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct idt77252_skb_prv) + sizeof(struct atm_skb_data));
-	return pci_register_driver(&idt77252_driver);
-}
-
-static void __exit idt77252_exit(void)
-{
-	struct idt77252_dev *card;
-	struct atm_dev *dev;
-
-	pci_unregister_driver(&idt77252_driver);
-
-	while (idt77252_chain) {
-		card = idt77252_chain;
-		dev = card->atmdev;
-		idt77252_chain = card->next;
-		timer_shutdown_sync(&card->tst_timer);
-
-		if (dev->phy->stop)
-			dev->phy->stop(dev);
-		deinit_card(card);
-		pci_disable_device(card->pcidev);
-		kfree(card);
-	}
-
-	DIPRINTK("idt77252: finished cleanup-module().\n");
-}
-
-module_init(idt77252_init);
-module_exit(idt77252_exit);
-
-MODULE_LICENSE("GPL");
-
-module_param(vpibits, uint, 0);
-MODULE_PARM_DESC(vpibits, "number of VPI bits supported (0, 1, or 2)");
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-module_param(debug, ulong, 0644);
-MODULE_PARM_DESC(debug,   "debug bitmap, see drivers/atm/idt77252.h");
-#endif
-
-MODULE_AUTHOR("Eddie C. Dost <ecd@atecom.com>");
-MODULE_DESCRIPTION("IDT77252 ABR SAR Driver");
diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h
deleted file mode 100644
index b059d31..0000000
--- a/drivers/atm/idt77252.h
+++ /dev/null
@@ -1,816 +0,0 @@
-/******************************************************************* 
- *
- * Copyright (c) 2000 ATecoM GmbH 
- *
- * The author may be reached at ecd@atecom.com.
- *
- * 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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR   IMPLIED
- * WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
- * NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
- * USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * 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.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *******************************************************************/
-
-#ifndef _IDT77252_H
-#define _IDT77252_H 1
-
-
-#include <linux/ptrace.h>
-#include <linux/skbuff.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-
-/*****************************************************************************/
-/*                                                                           */
-/* Makros                                                                    */
-/*                                                                           */
-/*****************************************************************************/
-#define VPCI2VC(card, vpi, vci) \
-        (((vpi) << card->vcibits) | ((vci) & card->vcimask))
-
-/*****************************************************************************/
-/*                                                                           */
-/*   DEBUGGING definitions                                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-#define DBG_RAW_CELL	0x00000400
-#define DBG_TINY	0x00000200
-#define DBG_GENERAL     0x00000100
-#define DBG_XGENERAL    0x00000080
-#define DBG_INIT        0x00000040
-#define DBG_DEINIT      0x00000020
-#define DBG_INTERRUPT   0x00000010
-#define DBG_OPEN_CONN   0x00000008
-#define DBG_CLOSE_CONN  0x00000004
-#define DBG_RX_DATA     0x00000002
-#define DBG_TX_DATA     0x00000001
-
-#ifdef CONFIG_ATM_IDT77252_DEBUG
-
-#define CPRINTK(args...)   do { if (debug & DBG_CLOSE_CONN) printk(args); } while(0)
-#define OPRINTK(args...)   do { if (debug & DBG_OPEN_CONN)  printk(args); } while(0)
-#define IPRINTK(args...)   do { if (debug & DBG_INIT)       printk(args); } while(0)
-#define INTPRINTK(args...) do { if (debug & DBG_INTERRUPT)  printk(args); } while(0)
-#define DIPRINTK(args...)  do { if (debug & DBG_DEINIT)     printk(args); } while(0)
-#define TXPRINTK(args...)  do { if (debug & DBG_TX_DATA)    printk(args); } while(0)
-#define RXPRINTK(args...)  do { if (debug & DBG_RX_DATA)    printk(args); } while(0)
-#define XPRINTK(args...)   do { if (debug & DBG_XGENERAL)   printk(args); } while(0)
-#define DPRINTK(args...)   do { if (debug & DBG_GENERAL)    printk(args); } while(0)
-#define NPRINTK(args...)   do { if (debug & DBG_TINY)	    printk(args); } while(0)
-#define RPRINTK(args...)   do { if (debug & DBG_RAW_CELL)   printk(args); } while(0)
-
-#else
-
-#define CPRINTK(args...)	do { } while(0)
-#define OPRINTK(args...)	do { } while(0)
-#define IPRINTK(args...)	do { } while(0)
-#define INTPRINTK(args...)	do { } while(0)
-#define DIPRINTK(args...)	do { } while(0)
-#define TXPRINTK(args...)	do { } while(0)
-#define RXPRINTK(args...)	do { } while(0)
-#define XPRINTK(args...)	do { } while(0)
-#define DPRINTK(args...)	do { } while(0)
-#define NPRINTK(args...)	do { } while(0)
-#define RPRINTK(args...)	do { } while(0)
-
-#endif
-
-#define SCHED_UBR0		0
-#define SCHED_UBR		1
-#define SCHED_VBR		2
-#define SCHED_ABR		3
-#define SCHED_CBR		4
-
-#define SCQFULL_TIMEOUT		HZ
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Free Buffer Queue Layout                                                */
-/*                                                                           */
-/*****************************************************************************/
-#define SAR_FB_SIZE_0		(2048 - 256)
-#define SAR_FB_SIZE_1		(4096 - 256)
-#define SAR_FB_SIZE_2		(8192 - 256)
-#define SAR_FB_SIZE_3		(16384 - 256)
-
-#define SAR_FBQ0_LOW		4
-#define SAR_FBQ0_HIGH		8
-#define SAR_FBQ1_LOW		2
-#define SAR_FBQ1_HIGH		4
-#define SAR_FBQ2_LOW		1
-#define SAR_FBQ2_HIGH		2
-#define SAR_FBQ3_LOW		1
-#define SAR_FBQ3_HIGH		2
-
-#if 0
-#define SAR_TST_RESERVED	44	/* Num TST reserved for UBR/ABR/VBR */
-#else
-#define SAR_TST_RESERVED	0	/* Num TST reserved for UBR/ABR/VBR */
-#endif
-
-#define TCT_CBR			0x00000000
-#define TCT_UBR			0x00000000
-#define TCT_VBR			0x40000000
-#define TCT_ABR			0x80000000
-#define TCT_TYPE		0xc0000000
-
-#define TCT_RR			0x20000000
-#define TCT_LMCR		0x08000000
-#define TCT_SCD_MASK		0x0007ffff
-
-#define TCT_TSIF		0x00004000
-#define TCT_HALT		0x80000000
-#define TCT_IDLE		0x40000000
-#define TCT_FLAG_UBR		0x80000000
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Structure describing an IDT77252                                        */
-/*                                                                           */
-/*****************************************************************************/
-
-struct scqe
-{
-	u32		word_1;
-	u32		word_2;
-	u32		word_3;
-	u32		word_4;
-};
-
-#define SCQ_ENTRIES	64
-#define SCQ_SIZE	(SCQ_ENTRIES * sizeof(struct scqe))
-#define SCQ_MASK	(SCQ_SIZE - 1)
-
-struct scq_info
-{
-	struct scqe		*base;
-	struct scqe		*next;
-	struct scqe		*last;
-	dma_addr_t		paddr;
-	spinlock_t		lock;
-	atomic_t		used;
-	unsigned long		trans_start;
-        unsigned long		scd;
-	spinlock_t		skblock;
-	struct sk_buff_head	transmit;
-	struct sk_buff_head	pending;
-};
-
-struct rx_pool {
-	struct sk_buff_head	queue;
-	unsigned int		len;
-};
-
-struct aal1 {
-	unsigned int		total;
-	unsigned int		count;
-	struct sk_buff		*data;
-	unsigned char		sequence;
-};
-
-struct vc_map;
-
-struct rate_estimator {
-	struct timer_list	timer;
-	unsigned int		interval;
-	unsigned int		ewma_log;
-	u64			cells;
-	u64			last_cells;
-	long			avcps;
-	u32			cps;
-	u32			maxcps;
-	struct vc_map		*vc;
-};
-
-struct vc_map {
-	unsigned int		index;
-	unsigned long		flags;
-#define VCF_TX		0
-#define VCF_RX		1
-#define VCF_IDLE	2
-#define VCF_RSV		3
-	unsigned int		class;
-	u8			init_er;
-	u8			lacr;
-	u8			max_er;
-	unsigned int		ntste;
-	spinlock_t		lock;
-	struct atm_vcc		*tx_vcc;
-	struct atm_vcc		*rx_vcc;
-	struct idt77252_dev	*card;
-	struct scq_info		*scq;		/* To keep track of the SCQ */
-	struct rate_estimator	*estimator;
-	int			scd_index;
-	union {
-		struct rx_pool	rx_pool;
-		struct aal1	aal1;
-	} rcv;
-};
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RCTE - Receive Connection Table Entry                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-struct rct_entry
-{
-	u32		word_1;
-	u32		buffer_handle;
-	u32		dma_address;
-	u32		aal5_crc32;
-};
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RSQ - Receive Status Queue                                              */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RSQE_VALID      0x80000000
-#define SAR_RSQE_IDLE       0x40000000
-#define SAR_RSQE_BUF_MASK   0x00030000
-#define SAR_RSQE_BUF_ASGN   0x00008000
-#define SAR_RSQE_NZGFC      0x00004000
-#define SAR_RSQE_EPDU       0x00002000
-#define SAR_RSQE_BUF_CONT   0x00001000
-#define SAR_RSQE_EFCIE      0x00000800
-#define SAR_RSQE_CLP        0x00000400
-#define SAR_RSQE_CRC        0x00000200
-#define SAR_RSQE_CELLCNT    0x000001FF
-
-
-#define RSQSIZE            8192
-#define RSQ_NUM_ENTRIES    (RSQSIZE / 16)
-#define RSQ_ALIGNMENT      8192
-
-struct rsq_entry {
-	u32			word_1;
-	u32			word_2;
-	u32			word_3;
-	u32			word_4;
-};
-
-struct rsq_info {
-	struct rsq_entry	*base;
-	struct rsq_entry	*next;
-	struct rsq_entry	*last;
-	dma_addr_t		paddr;
-};
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TSQ - Transmit Status Queue                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TSQE_INVALID         0x80000000
-#define SAR_TSQE_TIMESTAMP       0x00FFFFFF
-#define SAR_TSQE_TYPE		 0x60000000
-#define SAR_TSQE_TYPE_TIMER      0x00000000
-#define SAR_TSQE_TYPE_TSR        0x20000000
-#define SAR_TSQE_TYPE_IDLE       0x40000000
-#define SAR_TSQE_TYPE_TBD_COMP   0x60000000
-
-#define SAR_TSQE_TAG(stat)	(((stat) >> 24) & 0x1f)
-
-#define TSQSIZE            8192
-#define TSQ_NUM_ENTRIES    1024
-#define TSQ_ALIGNMENT      8192
-
-struct tsq_entry
-{
-	u32			word_1;
-	u32			word_2;
-};
-
-struct tsq_info
-{
-	struct tsq_entry	*base;
-	struct tsq_entry	*next;
-	struct tsq_entry	*last;
-	dma_addr_t		paddr;
-};
-
-struct tst_info
-{
-	struct vc_map		*vc;
-	u32			tste;
-};
-
-#define TSTE_MASK		0x601fffff
-
-#define TSTE_OPC_MASK		0x60000000
-#define TSTE_OPC_NULL		0x00000000
-#define TSTE_OPC_CBR		0x20000000
-#define TSTE_OPC_VAR		0x40000000
-#define TSTE_OPC_JMP		0x60000000
-
-#define TSTE_PUSH_IDLE		0x01000000
-#define TSTE_PUSH_ACTIVE	0x02000000
-
-#define TST_SWITCH_DONE		0
-#define TST_SWITCH_PENDING	1
-#define TST_SWITCH_WAIT		2
-
-#define FBQ_SHIFT		9
-#define FBQ_SIZE		(1 << FBQ_SHIFT)
-#define FBQ_MASK		(FBQ_SIZE - 1)
-
-struct sb_pool
-{
-	unsigned int		index;
-	struct sk_buff		*skb[FBQ_SIZE];
-};
-
-#define POOL_HANDLE(queue, index)	(((queue + 1) << 16) | (index))
-#define POOL_QUEUE(handle)		(((handle) >> 16) - 1)
-#define POOL_INDEX(handle)		((handle) & 0xffff)
-
-struct idt77252_dev
-{
-        struct tsq_info		tsq;		/* Transmit Status Queue */
-        struct rsq_info		rsq;		/* Receive Status Queue */
-
-	struct pci_dev		*pcidev;	/* PCI handle (desriptor) */
-	struct atm_dev		*atmdev;	/* ATM device desriptor */
-
-	void __iomem		*membase;	/* SAR's memory base address */
-	unsigned long		srambase;	/* SAR's sram  base address */
-	void __iomem		*fbq[4];	/* FBQ fill addresses */
-
-	struct mutex		mutex;
-	spinlock_t		cmd_lock;	/* for r/w utility/sram */
-
-	unsigned long		softstat;
-	unsigned long		flags;		/* see blow */
-
-	struct work_struct	tqueue;
-
-	unsigned long		tct_base;	/* TCT base address in SRAM */
-        unsigned long		rct_base;	/* RCT base address in SRAM */
-        unsigned long		rt_base;	/* Rate Table base in SRAM */
-        unsigned long		scd_base;	/* SCD base address in SRAM */
-        unsigned long		tst[2];		/* TST base address in SRAM */
-	unsigned long		abrst_base;	/* ABRST base address in SRAM */
-        unsigned long		fifo_base;	/* RX FIFO base in SRAM */
-
-	unsigned long		irqstat[16];
-
-	unsigned int		sramsize;	/* SAR's sram size */
-
-        unsigned int		tct_size;	/* total TCT entries */
-        unsigned int		rct_size;	/* total RCT entries */
-        unsigned int		scd_size;	/* length of SCD */
-        unsigned int		tst_size;	/* total TST entries */
-        unsigned int		tst_free;	/* free TSTEs in TST */
-        unsigned int		abrst_size;	/* size of ABRST in words */
-        unsigned int		fifo_size;	/* size of RX FIFO in words */
-
-        unsigned int		vpibits;	/* Bits used for VPI index */
-        unsigned int		vcibits;	/* Bits used for VCI index */
-        unsigned int		vcimask;	/* Mask for VCI index */
-
-	unsigned int		utopia_pcr;	/* Utopia Itf's Cell Rate */
-	unsigned int		link_pcr;	/* PHY's Peek Cell Rate */
-
-	struct vc_map		**vcs;		/* Open Connections */
-	struct vc_map		**scd2vc;	/* SCD to Connection map */
-
-	struct tst_info		*soft_tst;	/* TST to Connection map */
-	unsigned int		tst_index;	/* Current TST in use */
-	struct timer_list	tst_timer;
-	spinlock_t		tst_lock;
-	unsigned long		tst_state;
-
-	struct sb_pool		sbpool[4];	/* Pool of RX skbuffs */
-	struct sk_buff		*raw_cell_head; /* Pointer to raw cell queue */
-	u32			*raw_cell_hnd;	/* Pointer to RCQ handle */
-	dma_addr_t		raw_cell_paddr;
-
-	int			index;		/* SAR's ID */
-	int			revision;	/* chip revision */
-
-	char			name[16];	/* Device name */
-
-	struct idt77252_dev	*next;
-};
-
-
-/* definition for flag field above */
-#define IDT77252_BIT_INIT		1
-#define IDT77252_BIT_INTERRUPT		2
-
-
-#define ATM_CELL_PAYLOAD         48
-
-#define FREEBUF_ALIGNMENT        16
-
-/*****************************************************************************/
-/*                                                                           */
-/* Makros                                                                    */
-/*                                                                           */
-/*****************************************************************************/
-#define ALIGN_ADDRESS(addr, alignment) \
-        ((((u32)(addr)) + (((u32)(alignment))-1)) & ~(((u32)(alignment)) - 1))
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   ABR SAR Network operation Register                                      */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_REG_DR0	(card->membase + 0x00)
-#define SAR_REG_DR1	(card->membase + 0x04)
-#define SAR_REG_DR2	(card->membase + 0x08)
-#define SAR_REG_DR3	(card->membase + 0x0C)
-#define SAR_REG_CMD	(card->membase + 0x10)
-#define SAR_REG_CFG	(card->membase + 0x14)
-#define SAR_REG_STAT	(card->membase + 0x18)
-#define SAR_REG_RSQB	(card->membase + 0x1C)
-#define SAR_REG_RSQT	(card->membase + 0x20)
-#define SAR_REG_RSQH	(card->membase + 0x24)
-#define SAR_REG_CDC	(card->membase + 0x28)
-#define SAR_REG_VPEC	(card->membase + 0x2C)
-#define SAR_REG_ICC	(card->membase + 0x30)
-#define SAR_REG_RAWCT	(card->membase + 0x34)
-#define SAR_REG_TMR	(card->membase + 0x38)
-#define SAR_REG_TSTB	(card->membase + 0x3C)
-#define SAR_REG_TSQB	(card->membase + 0x40)
-#define SAR_REG_TSQT	(card->membase + 0x44)
-#define SAR_REG_TSQH	(card->membase + 0x48)
-#define SAR_REG_GP	(card->membase + 0x4C)
-#define SAR_REG_VPM	(card->membase + 0x50)
-#define SAR_REG_RXFD	(card->membase + 0x54)
-#define SAR_REG_RXFT	(card->membase + 0x58)
-#define SAR_REG_RXFH	(card->membase + 0x5C)
-#define SAR_REG_RAWHND	(card->membase + 0x60)
-#define SAR_REG_RXSTAT	(card->membase + 0x64)
-#define SAR_REG_ABRSTD	(card->membase + 0x68)
-#define SAR_REG_ABRRQ	(card->membase + 0x6C)
-#define SAR_REG_VBRRQ	(card->membase + 0x70)
-#define SAR_REG_RTBL	(card->membase + 0x74)
-#define SAR_REG_MDFCT	(card->membase + 0x78)
-#define SAR_REG_TXSTAT	(card->membase + 0x7C)
-#define SAR_REG_TCMDQ	(card->membase + 0x80)
-#define SAR_REG_IRCP	(card->membase + 0x84)
-#define SAR_REG_FBQP0	(card->membase + 0x88)
-#define SAR_REG_FBQP1	(card->membase + 0x8C)
-#define SAR_REG_FBQP2	(card->membase + 0x90)
-#define SAR_REG_FBQP3	(card->membase + 0x94)
-#define SAR_REG_FBQS0	(card->membase + 0x98)
-#define SAR_REG_FBQS1	(card->membase + 0x9C)
-#define SAR_REG_FBQS2	(card->membase + 0xA0)
-#define SAR_REG_FBQS3	(card->membase + 0xA4)
-#define SAR_REG_FBQWP0	(card->membase + 0xA8)
-#define SAR_REG_FBQWP1	(card->membase + 0xAC)
-#define SAR_REG_FBQWP2	(card->membase + 0xB0)
-#define SAR_REG_FBQWP3	(card->membase + 0xB4)
-#define SAR_REG_NOW	(card->membase + 0xB8)
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Commands                                                                */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_CMD_NO_OPERATION         0x00000000
-#define SAR_CMD_OPENCLOSE_CONNECTION 0x20000000
-#define SAR_CMD_WRITE_SRAM           0x40000000
-#define SAR_CMD_READ_SRAM            0x50000000
-#define SAR_CMD_READ_UTILITY         0x80000000
-#define SAR_CMD_WRITE_UTILITY        0x90000000
-
-#define SAR_CMD_OPEN_CONNECTION     (SAR_CMD_OPENCLOSE_CONNECTION | 0x00080000)
-#define SAR_CMD_CLOSE_CONNECTION     SAR_CMD_OPENCLOSE_CONNECTION
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Configuration Register bits                                             */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_CFG_SWRST          0x80000000  /* Software reset                 */
-#define SAR_CFG_LOOP           0x40000000  /* Internal Loopback              */
-#define SAR_CFG_RXPTH          0x20000000  /* Receive Path Enable            */
-#define SAR_CFG_IDLE_CLP       0x10000000  /* SAR set CLP Bits of Null Cells */
-#define SAR_CFG_TX_FIFO_SIZE_1 0x04000000  /* TX FIFO Size = 1 cell          */
-#define SAR_CFG_TX_FIFO_SIZE_2 0x08000000  /* TX FIFO Size = 2 cells         */
-#define SAR_CFG_TX_FIFO_SIZE_4 0x0C000000  /* TX FIFO Size = 4 cells         */
-#define SAR_CFG_TX_FIFO_SIZE_9 0x00000000  /* TX FIFO Size = 9 cells (full)  */
-#define SAR_CFG_NO_IDLE        0x02000000  /* SAR sends no Null Cells        */
-#define SAR_CFG_RSVD1          0x01000000  /* Reserved                       */
-#define SAR_CFG_RXSTQ_SIZE_2k  0x00000000  /* RX Stat Queue Size = 2048 byte */
-#define SAR_CFG_RXSTQ_SIZE_4k  0x00400000  /* RX Stat Queue Size = 4096 byte */
-#define SAR_CFG_RXSTQ_SIZE_8k  0x00800000  /* RX Stat Queue Size = 8192 byte */
-#define SAR_CFG_RXSTQ_SIZE_R   0x00C00000  /* RX Stat Queue Size = reserved  */
-#define SAR_CFG_ICAPT          0x00200000  /* accept Invalid Cells           */
-#define SAR_CFG_IGGFC          0x00100000  /* Ignore GFC                     */
-#define SAR_CFG_VPVCS_0        0x00000000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_1        0x00040000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_2        0x00080000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_VPVCS_8        0x000C0000  /* VPI/VCI Select bit range       */
-#define SAR_CFG_CNTBL_1k       0x00000000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_4k       0x00010000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_16k      0x00020000  /* Connection Table Size          */
-#define SAR_CFG_CNTBL_512      0x00030000  /* Connection Table Size          */
-#define SAR_CFG_VPECA          0x00008000  /* VPI/VCI Error Cell Accept      */
-#define SAR_CFG_RXINT_NOINT    0x00000000  /* No Interrupt on PDU received   */
-#define SAR_CFG_RXINT_NODELAY  0x00001000  /* Interrupt without delay to host*/
-#define SAR_CFG_RXINT_256US    0x00002000  /* Interrupt with delay 256 usec  */
-#define SAR_CFG_RXINT_505US    0x00003000  /* Interrupt with delay 505 usec  */
-#define SAR_CFG_RXINT_742US    0x00004000  /* Interrupt with delay 742 usec  */
-#define SAR_CFG_RAWIE          0x00000800  /* Raw Cell Queue Interrupt Enable*/
-#define SAR_CFG_RQFIE          0x00000400  /* RSQ Almost Full Int Enable     */
-#define SAR_CFG_RSVD2          0x00000200  /* Reserved                       */
-#define SAR_CFG_CACHE          0x00000100  /* DMA on Cache Line Boundary     */
-#define SAR_CFG_TMOIE          0x00000080  /* Timer Roll Over Int Enable     */
-#define SAR_CFG_FBIE           0x00000040  /* Free Buffer Queue Int Enable   */
-#define SAR_CFG_TXEN           0x00000020  /* Transmit Operation Enable      */
-#define SAR_CFG_TXINT          0x00000010  /* Transmit status Int Enable     */
-#define SAR_CFG_TXUIE          0x00000008  /* Transmit underrun Int Enable   */
-#define SAR_CFG_UMODE          0x00000004  /* Utopia Mode Select             */
-#define SAR_CFG_TXSFI          0x00000002  /* Transmit status Full Int Enable*/
-#define SAR_CFG_PHYIE          0x00000001  /* PHY Interrupt Enable           */
-
-#define SAR_CFG_TX_FIFO_SIZE_MASK 0x0C000000  /* TX FIFO Size Mask           */
-#define SAR_CFG_RXSTQSIZE_MASK 0x00C00000
-#define SAR_CFG_CNTBL_MASK     0x00030000
-#define SAR_CFG_RXINT_MASK     0x00007000
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   Status Register bits                                                    */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_STAT_FRAC_3     0xF0000000 /* Fraction of Free Buffer Queue 3 */
-#define SAR_STAT_FRAC_2     0x0F000000 /* Fraction of Free Buffer Queue 2 */
-#define SAR_STAT_FRAC_1     0x00F00000 /* Fraction of Free Buffer Queue 1 */
-#define SAR_STAT_FRAC_0     0x000F0000 /* Fraction of Free Buffer Queue 0 */
-#define SAR_STAT_TSIF       0x00008000 /* Transmit Status Indicator       */
-#define SAR_STAT_TXICP      0x00004000 /* Transmit Status Indicator       */
-#define SAR_STAT_RSVD1      0x00002000 /* Reserved                        */
-#define SAR_STAT_TSQF       0x00001000 /* Transmit Status Queue full      */
-#define SAR_STAT_TMROF      0x00000800 /* Timer overflow                  */
-#define SAR_STAT_PHYI       0x00000400 /* PHY device Interrupt flag       */
-#define SAR_STAT_CMDBZ      0x00000200 /* ABR SAR Command Busy Flag       */
-#define SAR_STAT_FBQ3A      0x00000100 /* Free Buffer Queue 3 Attention   */
-#define SAR_STAT_FBQ2A      0x00000080 /* Free Buffer Queue 2 Attention   */
-#define SAR_STAT_RSQF       0x00000040 /* Receive Status Queue full       */
-#define SAR_STAT_EPDU       0x00000020 /* End Of PDU Flag                 */
-#define SAR_STAT_RAWCF      0x00000010 /* Raw Cell Flag                   */ 
-#define SAR_STAT_FBQ1A      0x00000008 /* Free Buffer Queue 1 Attention   */
-#define SAR_STAT_FBQ0A      0x00000004 /* Free Buffer Queue 0 Attention   */
-#define SAR_STAT_RSQAF      0x00000002 /* Receive Status Queue almost full*/  
-#define SAR_STAT_RSVD2      0x00000001 /* Reserved                        */
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   General Purpose Register bits                                           */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_GP_TXNCC_MASK   0xff000000  /* Transmit Negative Credit Count   */
-#define SAR_GP_EEDI         0x00010000  /* EEPROM Data In                   */
-#define SAR_GP_BIGE         0x00008000  /* Big Endian Operation             */
-#define SAR_GP_RM_NORMAL    0x00000000  /* Normal handling of RM cells      */
-#define SAR_GP_RM_TO_RCQ    0x00002000  /* put RM cells into Raw Cell Queue */
-#define SAR_GP_RM_RSVD      0x00004000  /* Reserved                         */
-#define SAR_GP_RM_INHIBIT   0x00006000  /* Inhibit update of Connection tab */
-#define SAR_GP_PHY_RESET    0x00000008  /* PHY Reset                        */
-#define SAR_GP_EESCLK	    0x00000004	/* EEPROM SCLK			    */
-#define SAR_GP_EECS	    0x00000002	/* EEPROM Chip Select		    */
-#define SAR_GP_EEDO	    0x00000001	/* EEPROM Data Out		    */
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   SAR local SRAM layout for 128k work SRAM                                */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_SRAM_SCD_SIZE        12
-#define SAR_SRAM_TCT_SIZE         8
-#define SAR_SRAM_RCT_SIZE         4
-
-#define SAR_SRAM_TCT_128_BASE    0x00000
-#define SAR_SRAM_TCT_128_TOP     0x01fff
-#define SAR_SRAM_RCT_128_BASE    0x02000
-#define SAR_SRAM_RCT_128_TOP     0x02fff
-#define SAR_SRAM_FB0_128_BASE    0x03000
-#define SAR_SRAM_FB0_128_TOP     0x033ff
-#define SAR_SRAM_FB1_128_BASE    0x03400
-#define SAR_SRAM_FB1_128_TOP     0x037ff
-#define SAR_SRAM_FB2_128_BASE    0x03800
-#define SAR_SRAM_FB2_128_TOP     0x03bff
-#define SAR_SRAM_FB3_128_BASE    0x03c00
-#define SAR_SRAM_FB3_128_TOP     0x03fff
-#define SAR_SRAM_SCD_128_BASE    0x04000
-#define SAR_SRAM_SCD_128_TOP     0x07fff
-#define SAR_SRAM_TST1_128_BASE   0x08000
-#define SAR_SRAM_TST1_128_TOP    0x0bfff
-#define SAR_SRAM_TST2_128_BASE   0x0c000
-#define SAR_SRAM_TST2_128_TOP    0x0ffff
-#define SAR_SRAM_ABRSTD_128_BASE 0x10000
-#define SAR_SRAM_ABRSTD_128_TOP  0x13fff
-#define SAR_SRAM_RT_128_BASE     0x14000
-#define SAR_SRAM_RT_128_TOP      0x15fff
-
-#define SAR_SRAM_FIFO_128_BASE   0x18000
-#define SAR_SRAM_FIFO_128_TOP    0x1ffff
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   SAR local SRAM layout for 32k work SRAM                                 */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_SRAM_TCT_32_BASE     0x00000
-#define SAR_SRAM_TCT_32_TOP      0x00fff
-#define SAR_SRAM_RCT_32_BASE     0x01000
-#define SAR_SRAM_RCT_32_TOP      0x017ff
-#define SAR_SRAM_FB0_32_BASE     0x01800
-#define SAR_SRAM_FB0_32_TOP      0x01bff
-#define SAR_SRAM_FB1_32_BASE     0x01c00
-#define SAR_SRAM_FB1_32_TOP      0x01fff
-#define SAR_SRAM_FB2_32_BASE     0x02000
-#define SAR_SRAM_FB2_32_TOP      0x023ff
-#define SAR_SRAM_FB3_32_BASE     0x02400
-#define SAR_SRAM_FB3_32_TOP      0x027ff
-#define SAR_SRAM_SCD_32_BASE     0x02800
-#define SAR_SRAM_SCD_32_TOP      0x03fff
-#define SAR_SRAM_TST1_32_BASE    0x04000
-#define SAR_SRAM_TST1_32_TOP     0x04fff
-#define SAR_SRAM_TST2_32_BASE    0x05000
-#define SAR_SRAM_TST2_32_TOP     0x05fff
-#define SAR_SRAM_ABRSTD_32_BASE  0x06000
-#define SAR_SRAM_ABRSTD_32_TOP   0x067ff
-#define SAR_SRAM_RT_32_BASE      0x06800
-#define SAR_SRAM_RT_32_TOP       0x06fff
-#define SAR_SRAM_FIFO_32_BASE    0x07000
-#define SAR_SRAM_FIFO_32_TOP     0x07fff
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TSR - Transmit Status Request                                           */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TSR_TYPE_TSR  0x80000000
-#define SAR_TSR_TYPE_TBD  0x00000000
-#define SAR_TSR_TSIF      0x20000000
-#define SAR_TSR_TAG_MASK  0x01F00000
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   TBD - Transmit Buffer Descriptor                                        */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_TBD_EPDU      0x40000000
-#define SAR_TBD_TSIF      0x20000000
-#define SAR_TBD_OAM       0x10000000
-#define SAR_TBD_AAL0      0x00000000
-#define SAR_TBD_AAL34     0x04000000
-#define SAR_TBD_AAL5      0x08000000
-#define SAR_TBD_GTSI      0x02000000
-#define SAR_TBD_TAG_MASK  0x01F00000
-
-#define SAR_TBD_VPI_MASK  0x0FF00000
-#define SAR_TBD_VCI_MASK  0x000FFFF0
-#define SAR_TBD_VC_MASK   (SAR_TBD_VPI_MASK | SAR_TBD_VCI_MASK)
-
-#define SAR_TBD_VPI_SHIFT 20
-#define SAR_TBD_VCI_SHIFT 4
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RXFD - Receive FIFO Descriptor                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RXFD_SIZE_MASK     0x0F000000
-#define SAR_RXFD_SIZE_512      0x00000000  /* 512 words                      */
-#define SAR_RXFD_SIZE_1K       0x01000000  /* 1k words                       */
-#define SAR_RXFD_SIZE_2K       0x02000000  /* 2k words                       */
-#define SAR_RXFD_SIZE_4K       0x03000000  /* 4k words                       */
-#define SAR_RXFD_SIZE_8K       0x04000000  /* 8k words                       */
-#define SAR_RXFD_SIZE_16K      0x05000000  /* 16k words                      */
-#define SAR_RXFD_SIZE_32K      0x06000000  /* 32k words                      */
-#define SAR_RXFD_SIZE_64K      0x07000000  /* 64k words                      */
-#define SAR_RXFD_SIZE_128K     0x08000000  /* 128k words                     */
-#define SAR_RXFD_SIZE_256K     0x09000000  /* 256k words                     */
-#define SAR_RXFD_ADDR_MASK     0x001ffc00
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   ABRSTD - ABR + VBR Schedule Tables                                      */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_ABRSTD_SIZE_MASK   0x07000000
-#define SAR_ABRSTD_SIZE_512    0x00000000  /* 512 words                      */
-#define SAR_ABRSTD_SIZE_1K     0x01000000  /* 1k words                       */
-#define SAR_ABRSTD_SIZE_2K     0x02000000  /* 2k words                       */
-#define SAR_ABRSTD_SIZE_4K     0x03000000  /* 4k words                       */
-#define SAR_ABRSTD_SIZE_8K     0x04000000  /* 8k words                       */
-#define SAR_ABRSTD_SIZE_16K    0x05000000  /* 16k words                      */
-#define SAR_ABRSTD_ADDR_MASK   0x001ffc00
-
-
-/*****************************************************************************/
-/*                                                                           */
-/*   RCTE - Receive Connection Table Entry                                   */
-/*                                                                           */
-/*****************************************************************************/
-
-#define SAR_RCTE_IL_MASK       0xE0000000  /* inactivity limit               */
-#define SAR_RCTE_IC_MASK       0x1C000000  /* inactivity count               */
-#define SAR_RCTE_RSVD          0x02000000  /* reserved                       */
-#define SAR_RCTE_LCD           0x01000000  /* last cell data                 */
-#define SAR_RCTE_CI_VC         0x00800000  /* EFCI in previous cell of VC    */
-#define SAR_RCTE_FBP_01        0x00000000  /* 1. cell->FBQ0, others->FBQ1    */
-#define SAR_RCTE_FBP_1         0x00200000  /* use FBQ 1 for all cells        */
-#define SAR_RCTE_FBP_2         0x00400000  /* use FBQ 2 for all cells        */
-#define SAR_RCTE_FBP_3         0x00600000  /* use FBQ 3 for all cells        */
-#define SAR_RCTE_NZ_GFC        0x00100000  /* non zero GFC in all cell of VC */
-#define SAR_RCTE_CONNECTOPEN   0x00080000  /* VC is open                     */
-#define SAR_RCTE_AAL_MASK      0x00070000  /* mask for AAL type field s.b.   */
-#define SAR_RCTE_RAWCELLINTEN  0x00008000  /* raw cell interrupt enable      */
-#define SAR_RCTE_RXCONCELLADDR 0x00004000  /* RX constant cell address       */
-#define SAR_RCTE_BUFFSTAT_MASK 0x00003000  /* buffer status                  */
-#define SAR_RCTE_EFCI          0x00000800  /* EFCI Congestion flag           */
-#define SAR_RCTE_CLP           0x00000400  /* Cell Loss Priority flag        */
-#define SAR_RCTE_CRC           0x00000200  /* Received CRC Error             */
-#define SAR_RCTE_CELLCNT_MASK  0x000001FF  /* cell Count                     */
-
-#define SAR_RCTE_AAL0          0x00000000  /* AAL types for ALL field        */
-#define SAR_RCTE_AAL34         0x00010000
-#define SAR_RCTE_AAL5          0x00020000
-#define SAR_RCTE_RCQ           0x00030000
-#define SAR_RCTE_OAM           0x00040000
-
-#define TCMDQ_START		0x01000000
-#define TCMDQ_LACR		0x02000000
-#define TCMDQ_START_LACR	0x03000000
-#define TCMDQ_INIT_ER		0x04000000
-#define TCMDQ_HALT		0x05000000
-
-
-struct idt77252_skb_prv {
-	struct scqe	tbd;	/* Transmit Buffer Descriptor */
-	dma_addr_t	paddr;	/* DMA handle */
-	u32		pool;	/* sb_pool handle */
-} __packed;
-
-#define IDT77252_PRV_TBD(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->tbd)
-#define IDT77252_PRV_PADDR(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->paddr)
-#define IDT77252_PRV_POOL(skb)	\
-	(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->pool)
-
-/*****************************************************************************/
-/*                                                                           */
-/*   PCI related items                                                       */
-/*                                                                           */
-/*****************************************************************************/
-
-#ifndef PCI_VENDOR_ID_IDT
-#define PCI_VENDOR_ID_IDT 0x111D
-#endif /* PCI_VENDOR_ID_IDT */
-
-#ifndef PCI_DEVICE_ID_IDT_IDT77252
-#define PCI_DEVICE_ID_IDT_IDT77252 0x0003
-#endif /* PCI_DEVICE_ID_IDT_IDT772052 */
-
-
-#endif /* !(_IDT77252_H) */
diff --git a/drivers/atm/idt77252_tables.h b/drivers/atm/idt77252_tables.h
deleted file mode 100644
index 12b81e0..0000000
--- a/drivers/atm/idt77252_tables.h
+++ /dev/null
@@ -1,781 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Do not edit, automatically generated by `./genrtbl'.
- *
- * Cell Line Rate: 353207.55 (155520000 bps)
- */
-
-static unsigned int log_to_rate[] =
-{
-/* 000 */ 0x8d022e27, /* cps =     10.02, nrm =  3, interval = 35264.00 */
-/* 001 */ 0x8d362e11, /* cps =     10.42, nrm =  3, interval = 33856.00 */
-/* 002 */ 0x8d6e2bf8, /* cps =     10.86, nrm =  3, interval = 32512.00 */
-/* 003 */ 0x8da82bcf, /* cps =     11.31, nrm =  3, interval = 31200.00 */
-/* 004 */ 0x8de42ba8, /* cps =     11.78, nrm =  3, interval = 29952.00 */
-/* 005 */ 0x8e242b82, /* cps =     12.28, nrm =  3, interval = 28736.00 */
-/* 006 */ 0x8e662b5e, /* cps =     12.80, nrm =  3, interval = 27584.00 */
-/* 007 */ 0x8eaa2b3c, /* cps =     13.33, nrm =  3, interval = 26496.00 */
-/* 008 */ 0x8ef22b1a, /* cps =     13.89, nrm =  3, interval = 25408.00 */
-/* 009 */ 0x8f3e2afa, /* cps =     14.48, nrm =  3, interval = 24384.00 */
-/* 010 */ 0x8f8a2adc, /* cps =     15.08, nrm =  3, interval = 23424.00 */
-/* 011 */ 0x8fdc2abe, /* cps =     15.72, nrm =  3, interval = 22464.00 */
-/* 012 */ 0x90182aa2, /* cps =     16.38, nrm =  3, interval = 21568.00 */
-/* 013 */ 0x90422a87, /* cps =     17.03, nrm =  3, interval = 20704.00 */
-/* 014 */ 0x90702a6d, /* cps =     17.75, nrm =  3, interval = 19872.00 */
-/* 015 */ 0x90a02a54, /* cps =     18.50, nrm =  3, interval = 19072.00 */
-/* 016 */ 0x90d22a3c, /* cps =     19.28, nrm =  3, interval = 18304.00 */
-/* 017 */ 0x91062a25, /* cps =     20.09, nrm =  3, interval = 17568.00 */
-/* 018 */ 0x913c2a0f, /* cps =     20.94, nrm =  3, interval = 16864.00 */
-/* 019 */ 0x917427f3, /* cps =     21.81, nrm =  3, interval = 16176.00 */
-/* 020 */ 0x91b027ca, /* cps =     22.75, nrm =  3, interval = 15520.00 */
-/* 021 */ 0x91ec27a3, /* cps =     23.69, nrm =  3, interval = 14896.00 */
-/* 022 */ 0x922c277e, /* cps =     24.69, nrm =  3, interval = 14304.00 */
-/* 023 */ 0x926e275a, /* cps =     25.72, nrm =  3, interval = 13728.00 */
-/* 024 */ 0x92b42737, /* cps =     26.81, nrm =  3, interval = 13168.00 */
-/* 025 */ 0x92fc2716, /* cps =     27.94, nrm =  3, interval = 12640.00 */
-/* 026 */ 0x934626f6, /* cps =     29.09, nrm =  3, interval = 12128.00 */
-/* 027 */ 0x939426d8, /* cps =     30.31, nrm =  3, interval = 11648.00 */
-/* 028 */ 0x93e426bb, /* cps =     31.56, nrm =  3, interval = 11184.00 */
-/* 029 */ 0x941e269e, /* cps =     32.94, nrm =  3, interval = 10720.00 */
-/* 030 */ 0x944a2683, /* cps =     34.31, nrm =  3, interval = 10288.00 */
-/* 031 */ 0x9476266a, /* cps =     35.69, nrm =  3, interval =  9888.00 */
-/* 032 */ 0x94a62651, /* cps =     37.19, nrm =  3, interval =  9488.00 */
-/* 033 */ 0x94d82639, /* cps =     38.75, nrm =  3, interval =  9104.00 */
-/* 034 */ 0x950c6622, /* cps =     40.38, nrm =  4, interval =  8736.00 */
-/* 035 */ 0x9544660c, /* cps =     42.12, nrm =  4, interval =  8384.00 */
-/* 036 */ 0x957c63ee, /* cps =     43.88, nrm =  4, interval =  8048.00 */
-/* 037 */ 0x95b663c6, /* cps =     45.69, nrm =  4, interval =  7728.00 */
-/* 038 */ 0x95f4639f, /* cps =     47.62, nrm =  4, interval =  7416.00 */
-/* 039 */ 0x96346379, /* cps =     49.62, nrm =  4, interval =  7112.00 */
-/* 040 */ 0x96766356, /* cps =     51.69, nrm =  4, interval =  6832.00 */
-/* 041 */ 0x96bc6333, /* cps =     53.88, nrm =  4, interval =  6552.00 */
-/* 042 */ 0x97046312, /* cps =     56.12, nrm =  4, interval =  6288.00 */
-/* 043 */ 0x974e62f3, /* cps =     58.44, nrm =  4, interval =  6040.00 */
-/* 044 */ 0x979e62d4, /* cps =     60.94, nrm =  4, interval =  5792.00 */
-/* 045 */ 0x97f062b7, /* cps =     63.50, nrm =  4, interval =  5560.00 */
-/* 046 */ 0x9822629b, /* cps =     66.12, nrm =  4, interval =  5336.00 */
-/* 047 */ 0x984e6280, /* cps =     68.88, nrm =  4, interval =  5120.00 */
-/* 048 */ 0x987e6266, /* cps =     71.88, nrm =  4, interval =  4912.00 */
-/* 049 */ 0x98ac624e, /* cps =     74.75, nrm =  4, interval =  4720.00 */
-/* 050 */ 0x98e06236, /* cps =     78.00, nrm =  4, interval =  4528.00 */
-/* 051 */ 0x9914a21f, /* cps =     81.25, nrm =  8, interval =  4344.00 */
-/* 052 */ 0x994aa209, /* cps =     84.62, nrm =  8, interval =  4168.00 */
-/* 053 */ 0x99829fe9, /* cps =     88.12, nrm =  8, interval =  4004.00 */
-/* 054 */ 0x99be9fc1, /* cps =     91.88, nrm =  8, interval =  3844.00 */
-/* 055 */ 0x99fc9f9a, /* cps =     95.75, nrm =  8, interval =  3688.00 */
-/* 056 */ 0x9a3c9f75, /* cps =     99.75, nrm =  8, interval =  3540.00 */
-/* 057 */ 0x9a809f51, /* cps =    104.00, nrm =  8, interval =  3396.00 */
-/* 058 */ 0x9ac49f2f, /* cps =    108.25, nrm =  8, interval =  3260.00 */
-/* 059 */ 0x9b0e9f0e, /* cps =    112.88, nrm =  8, interval =  3128.00 */
-/* 060 */ 0x9b589eef, /* cps =    117.50, nrm =  8, interval =  3004.00 */
-/* 061 */ 0x9ba69ed1, /* cps =    122.38, nrm =  8, interval =  2884.00 */
-/* 062 */ 0x9bf89eb4, /* cps =    127.50, nrm =  8, interval =  2768.00 */
-/* 063 */ 0x9c269e98, /* cps =    132.75, nrm =  8, interval =  2656.00 */
-/* 064 */ 0x9c549e7d, /* cps =    138.50, nrm =  8, interval =  2548.00 */
-/* 065 */ 0x9c849e63, /* cps =    144.50, nrm =  8, interval =  2444.00 */
-/* 066 */ 0x9cb29e4b, /* cps =    150.25, nrm =  8, interval =  2348.00 */
-/* 067 */ 0x9ce69e33, /* cps =    156.75, nrm =  8, interval =  2252.00 */
-/* 068 */ 0x9d1cde1c, /* cps =    163.50, nrm = 16, interval =  2160.00 */
-/* 069 */ 0x9d50de07, /* cps =    170.00, nrm = 16, interval =  2076.00 */
-/* 070 */ 0x9d8adbe4, /* cps =    177.25, nrm = 16, interval =  1992.00 */
-/* 071 */ 0x9dc4dbbc, /* cps =    184.50, nrm = 16, interval =  1912.00 */
-/* 072 */ 0x9e02db96, /* cps =    192.25, nrm = 16, interval =  1836.00 */
-/* 073 */ 0x9e42db71, /* cps =    200.25, nrm = 16, interval =  1762.00 */
-/* 074 */ 0x9e86db4d, /* cps =    208.75, nrm = 16, interval =  1690.00 */
-/* 075 */ 0x9ecedb2b, /* cps =    217.75, nrm = 16, interval =  1622.00 */
-/* 076 */ 0x9f16db0a, /* cps =    226.75, nrm = 16, interval =  1556.00 */
-/* 077 */ 0x9f62daeb, /* cps =    236.25, nrm = 16, interval =  1494.00 */
-/* 078 */ 0x9fb2dacd, /* cps =    246.25, nrm = 16, interval =  1434.00 */
-/* 079 */ 0xa002dab0, /* cps =    256.50, nrm = 16, interval =  1376.00 */
-/* 080 */ 0xa02eda94, /* cps =    267.50, nrm = 16, interval =  1320.00 */
-/* 081 */ 0xa05ada7a, /* cps =    278.50, nrm = 16, interval =  1268.00 */
-/* 082 */ 0xa088da60, /* cps =    290.00, nrm = 16, interval =  1216.00 */
-/* 083 */ 0xa0b8da48, /* cps =    302.00, nrm = 16, interval =  1168.00 */
-/* 084 */ 0xa0ecda30, /* cps =    315.00, nrm = 16, interval =  1120.00 */
-/* 085 */ 0xa1211a1a, /* cps =    328.00, nrm = 32, interval =  1076.00 */
-/* 086 */ 0xa1591a04, /* cps =    342.00, nrm = 32, interval =  1032.00 */
-/* 087 */ 0xa19117df, /* cps =    356.00, nrm = 32, interval =   991.00 */
-/* 088 */ 0xa1cd17b7, /* cps =    371.00, nrm = 32, interval =   951.00 */
-/* 089 */ 0xa20b1791, /* cps =    386.50, nrm = 32, interval =   913.00 */
-/* 090 */ 0xa24d176c, /* cps =    403.00, nrm = 32, interval =   876.00 */
-/* 091 */ 0xa28f1749, /* cps =    419.50, nrm = 32, interval =   841.00 */
-/* 092 */ 0xa2d71727, /* cps =    437.50, nrm = 32, interval =   807.00 */
-/* 093 */ 0xa31f1707, /* cps =    455.50, nrm = 32, interval =   775.00 */
-/* 094 */ 0xa36d16e7, /* cps =    475.00, nrm = 32, interval =   743.00 */
-/* 095 */ 0xa3bd16c9, /* cps =    495.00, nrm = 32, interval =   713.00 */
-/* 096 */ 0xa40716ad, /* cps =    515.00, nrm = 32, interval =   685.00 */
-/* 097 */ 0xa4331691, /* cps =    537.00, nrm = 32, interval =   657.00 */
-/* 098 */ 0xa45f1677, /* cps =    559.00, nrm = 32, interval =   631.00 */
-/* 099 */ 0xa48f165d, /* cps =    583.00, nrm = 32, interval =   605.00 */
-/* 100 */ 0xa4bf1645, /* cps =    607.00, nrm = 32, interval =   581.00 */
-/* 101 */ 0xa4f1162e, /* cps =    632.00, nrm = 32, interval =   558.00 */
-/* 102 */ 0xa5291617, /* cps =    660.00, nrm = 32, interval =   535.00 */
-/* 103 */ 0xa55f1602, /* cps =    687.00, nrm = 32, interval =   514.00 */
-/* 104 */ 0xa59913da, /* cps =    716.00, nrm = 32, interval =   493.00 */
-/* 105 */ 0xa5d513b2, /* cps =    746.00, nrm = 32, interval =   473.00 */
-/* 106 */ 0xa613138c, /* cps =    777.00, nrm = 32, interval =   454.00 */
-/* 107 */ 0xa6551368, /* cps =    810.00, nrm = 32, interval =   436.00 */
-/* 108 */ 0xa6971345, /* cps =    843.00, nrm = 32, interval =   418.50 */
-/* 109 */ 0xa6df1323, /* cps =    879.00, nrm = 32, interval =   401.50 */
-/* 110 */ 0xa7291303, /* cps =    916.00, nrm = 32, interval =   385.50 */
-/* 111 */ 0xa77512e4, /* cps =    954.00, nrm = 32, interval =   370.00 */
-/* 112 */ 0xa7c512c6, /* cps =    994.00, nrm = 32, interval =   355.00 */
-/* 113 */ 0xa80d12a9, /* cps =   1036.00, nrm = 32, interval =   340.50 */
-/* 114 */ 0xa839128e, /* cps =   1080.00, nrm = 32, interval =   327.00 */
-/* 115 */ 0xa8651274, /* cps =   1124.00, nrm = 32, interval =   314.00 */
-/* 116 */ 0xa895125a, /* cps =   1172.00, nrm = 32, interval =   301.00 */
-/* 117 */ 0xa8c71242, /* cps =   1222.00, nrm = 32, interval =   289.00 */
-/* 118 */ 0xa8f9122b, /* cps =   1272.00, nrm = 32, interval =   277.50 */
-/* 119 */ 0xa92f1214, /* cps =   1326.00, nrm = 32, interval =   266.00 */
-/* 120 */ 0xa9670ffe, /* cps =   1382.00, nrm = 32, interval =   255.50 */
-/* 121 */ 0xa9a10fd5, /* cps =   1440.00, nrm = 32, interval =   245.25 */
-/* 122 */ 0xa9db0fae, /* cps =   1498.00, nrm = 32, interval =   235.50 */
-/* 123 */ 0xaa1b0f88, /* cps =   1562.00, nrm = 32, interval =   226.00 */
-/* 124 */ 0xaa5d0f63, /* cps =   1628.00, nrm = 32, interval =   216.75 */
-/* 125 */ 0xaaa10f41, /* cps =   1696.00, nrm = 32, interval =   208.25 */
-/* 126 */ 0xaae90f1f, /* cps =   1768.00, nrm = 32, interval =   199.75 */
-/* 127 */ 0xab330eff, /* cps =   1842.00, nrm = 32, interval =   191.75 */
-/* 128 */ 0xab7f0ee0, /* cps =   1918.00, nrm = 32, interval =   184.00 */
-/* 129 */ 0xabd10ec2, /* cps =   2000.00, nrm = 32, interval =   176.50 */
-/* 130 */ 0xac110ea6, /* cps =   2080.00, nrm = 32, interval =   169.50 */
-/* 131 */ 0xac3d0e8b, /* cps =   2168.00, nrm = 32, interval =   162.75 */
-/* 132 */ 0xac6d0e70, /* cps =   2264.00, nrm = 32, interval =   156.00 */
-/* 133 */ 0xac9b0e57, /* cps =   2356.00, nrm = 32, interval =   149.75 */
-/* 134 */ 0xaccd0e3f, /* cps =   2456.00, nrm = 32, interval =   143.75 */
-/* 135 */ 0xacff0e28, /* cps =   2556.00, nrm = 32, interval =   138.00 */
-/* 136 */ 0xad350e12, /* cps =   2664.00, nrm = 32, interval =   132.50 */
-/* 137 */ 0xad6d0bf9, /* cps =   2776.00, nrm = 32, interval =   127.12 */
-/* 138 */ 0xada70bd0, /* cps =   2892.00, nrm = 32, interval =   122.00 */
-/* 139 */ 0xade30ba9, /* cps =   3012.00, nrm = 32, interval =   117.12 */
-/* 140 */ 0xae230b83, /* cps =   3140.00, nrm = 32, interval =   112.38 */
-/* 141 */ 0xae650b5f, /* cps =   3272.00, nrm = 32, interval =   107.88 */
-/* 142 */ 0xaeab0b3c, /* cps =   3412.00, nrm = 32, interval =   103.50 */
-/* 143 */ 0xaef10b1b, /* cps =   3552.00, nrm = 32, interval =    99.38 */
-/* 144 */ 0xaf3b0afb, /* cps =   3700.00, nrm = 32, interval =    95.38 */
-/* 145 */ 0xaf8b0adc, /* cps =   3860.00, nrm = 32, interval =    91.50 */
-/* 146 */ 0xafd90abf, /* cps =   4016.00, nrm = 32, interval =    87.88 */
-/* 147 */ 0xb0170aa3, /* cps =   4184.00, nrm = 32, interval =    84.38 */
-/* 148 */ 0xb0430a87, /* cps =   4360.00, nrm = 32, interval =    80.88 */
-/* 149 */ 0xb0710a6d, /* cps =   4544.00, nrm = 32, interval =    77.62 */
-/* 150 */ 0xb0a10a54, /* cps =   4736.00, nrm = 32, interval =    74.50 */
-/* 151 */ 0xb0d30a3c, /* cps =   4936.00, nrm = 32, interval =    71.50 */
-/* 152 */ 0xb1070a25, /* cps =   5144.00, nrm = 32, interval =    68.62 */
-/* 153 */ 0xb13d0a0f, /* cps =   5360.00, nrm = 32, interval =    65.88 */
-/* 154 */ 0xb17507f4, /* cps =   5584.00, nrm = 32, interval =    63.25 */
-/* 155 */ 0xb1af07cb, /* cps =   5816.00, nrm = 32, interval =    60.69 */
-/* 156 */ 0xb1eb07a4, /* cps =   6056.00, nrm = 32, interval =    58.25 */
-/* 157 */ 0xb22b077f, /* cps =   6312.00, nrm = 32, interval =    55.94 */
-/* 158 */ 0xb26d075b, /* cps =   6576.00, nrm = 32, interval =    53.69 */
-/* 159 */ 0xb2b30738, /* cps =   6856.00, nrm = 32, interval =    51.50 */
-/* 160 */ 0xb2fb0717, /* cps =   7144.00, nrm = 32, interval =    49.44 */
-/* 161 */ 0xb34506f7, /* cps =   7440.00, nrm = 32, interval =    47.44 */
-/* 162 */ 0xb39306d9, /* cps =   7752.00, nrm = 32, interval =    45.56 */
-/* 163 */ 0xb3e506bb, /* cps =   8080.00, nrm = 32, interval =    43.69 */
-/* 164 */ 0xb41d069f, /* cps =   8416.00, nrm = 32, interval =    41.94 */
-/* 165 */ 0xb4490684, /* cps =   8768.00, nrm = 32, interval =    40.25 */
-/* 166 */ 0xb477066a, /* cps =   9136.00, nrm = 32, interval =    38.62 */
-/* 167 */ 0xb4a70651, /* cps =   9520.00, nrm = 32, interval =    37.06 */
-/* 168 */ 0xb4d90639, /* cps =   9920.00, nrm = 32, interval =    35.56 */
-/* 169 */ 0xb50d0622, /* cps =  10336.00, nrm = 32, interval =    34.12 */
-/* 170 */ 0xb545060c, /* cps =  10784.00, nrm = 32, interval =    32.75 */
-/* 171 */ 0xb57b03ef, /* cps =  11216.00, nrm = 32, interval =    31.47 */
-/* 172 */ 0xb5b503c7, /* cps =  11680.00, nrm = 32, interval =    30.22 */
-/* 173 */ 0xb5f303a0, /* cps =  12176.00, nrm = 32, interval =    29.00 */
-/* 174 */ 0xb633037a, /* cps =  12688.00, nrm = 32, interval =    27.81 */
-/* 175 */ 0xb6750357, /* cps =  13216.00, nrm = 32, interval =    26.72 */
-/* 176 */ 0xb6bb0334, /* cps =  13776.00, nrm = 32, interval =    25.62 */
-/* 177 */ 0xb7030313, /* cps =  14352.00, nrm = 32, interval =    24.59 */
-/* 178 */ 0xb74f02f3, /* cps =  14960.00, nrm = 32, interval =    23.59 */
-/* 179 */ 0xb79d02d5, /* cps =  15584.00, nrm = 32, interval =    22.66 */
-/* 180 */ 0xb7ed02b8, /* cps =  16224.00, nrm = 32, interval =    21.75 */
-/* 181 */ 0xb821029c, /* cps =  16896.00, nrm = 32, interval =    20.88 */
-/* 182 */ 0xb84f0281, /* cps =  17632.00, nrm = 32, interval =    20.03 */
-/* 183 */ 0xb87d0267, /* cps =  18368.00, nrm = 32, interval =    19.22 */
-/* 184 */ 0xb8ad024e, /* cps =  19136.00, nrm = 32, interval =    18.44 */
-/* 185 */ 0xb8dd0237, /* cps =  19904.00, nrm = 32, interval =    17.72 */
-/* 186 */ 0xb9130220, /* cps =  20768.00, nrm = 32, interval =    17.00 */
-/* 187 */ 0xb949020a, /* cps =  21632.00, nrm = 32, interval =    16.31 */
-/* 188 */ 0xb98301f5, /* cps =  22560.00, nrm = 32, interval =    15.66 */
-/* 189 */ 0xb9bd01e1, /* cps =  23488.00, nrm = 32, interval =    15.03 */
-/* 190 */ 0xb9fd01cd, /* cps =  24512.00, nrm = 32, interval =    14.41 */
-/* 191 */ 0xba3b01bb, /* cps =  25504.00, nrm = 32, interval =    13.84 */
-/* 192 */ 0xba7f01a9, /* cps =  26592.00, nrm = 32, interval =    13.28 */
-/* 193 */ 0xbac30198, /* cps =  27680.00, nrm = 32, interval =    12.75 */
-/* 194 */ 0xbb0f0187, /* cps =  28896.00, nrm = 32, interval =    12.22 */
-/* 195 */ 0xbb570178, /* cps =  30048.00, nrm = 32, interval =    11.75 */
-/* 196 */ 0xbbab0168, /* cps =  31392.00, nrm = 32, interval =    11.25 */
-/* 197 */ 0xbbf9015a, /* cps =  32640.00, nrm = 32, interval =    10.81 */
-/* 198 */ 0xbc27014c, /* cps =  33984.00, nrm = 32, interval =    10.38 */
-/* 199 */ 0xbc53013f, /* cps =  35392.00, nrm = 32, interval =     9.97 */
-/* 200 */ 0xbc830132, /* cps =  36928.00, nrm = 32, interval =     9.56 */
-/* 201 */ 0xbcb50125, /* cps =  38528.00, nrm = 32, interval =     9.16 */
-/* 202 */ 0xbce5011a, /* cps =  40064.00, nrm = 32, interval =     8.81 */
-/* 203 */ 0xbd1d010e, /* cps =  41856.00, nrm = 32, interval =     8.44 */
-/* 204 */ 0xbd530103, /* cps =  43584.00, nrm = 32, interval =     8.09 */
-/* 205 */ 0xbd8b00f9, /* cps =  45376.00, nrm = 32, interval =     7.78 */
-/* 206 */ 0xbdc500ef, /* cps =  47232.00, nrm = 32, interval =     7.47 */
-/* 207 */ 0xbe0700e5, /* cps =  49344.00, nrm = 32, interval =     7.16 */
-/* 208 */ 0xbe4500dc, /* cps =  51328.00, nrm = 32, interval =     6.88 */
-/* 209 */ 0xbe8900d3, /* cps =  53504.00, nrm = 32, interval =     6.59 */
-/* 210 */ 0xbecb00cb, /* cps =  55616.00, nrm = 32, interval =     6.34 */
-/* 211 */ 0xbf1d00c2, /* cps =  58240.00, nrm = 32, interval =     6.06 */
-/* 212 */ 0xbf6100bb, /* cps =  60416.00, nrm = 32, interval =     5.84 */
-/* 213 */ 0xbfb500b3, /* cps =  63104.00, nrm = 32, interval =     5.59 */
-/* 214 */ 0xc00300ac, /* cps =  65664.00, nrm = 32, interval =     5.38 */
-/* 215 */ 0xc02f00a5, /* cps =  68480.00, nrm = 32, interval =     5.16 */
-/* 216 */ 0xc05d009e, /* cps =  71424.00, nrm = 32, interval =     4.94 */
-/* 217 */ 0xc0890098, /* cps =  74240.00, nrm = 32, interval =     4.75 */
-/* 218 */ 0xc0b90092, /* cps =  77312.00, nrm = 32, interval =     4.56 */
-/* 219 */ 0xc0ed008c, /* cps =  80640.00, nrm = 32, interval =     4.38 */
-/* 220 */ 0xc1250086, /* cps =  84224.00, nrm = 32, interval =     4.19 */
-/* 221 */ 0xc1590081, /* cps =  87552.00, nrm = 32, interval =     4.03 */
-/* 222 */ 0xc191007c, /* cps =  91136.00, nrm = 32, interval =     3.88 */
-/* 223 */ 0xc1cd0077, /* cps =  94976.00, nrm = 32, interval =     3.72 */
-/* 224 */ 0xc20d0072, /* cps =  99072.00, nrm = 32, interval =     3.56 */
-/* 225 */ 0xc255006d, /* cps = 103680.00, nrm = 32, interval =     3.41 */
-/* 226 */ 0xc2910069, /* cps = 107520.00, nrm = 32, interval =     3.28 */
-/* 227 */ 0xc2d50065, /* cps = 111872.00, nrm = 32, interval =     3.16 */
-/* 228 */ 0xc32f0060, /* cps = 117632.00, nrm = 32, interval =     3.00 */
-/* 229 */ 0xc36b005d, /* cps = 121472.00, nrm = 32, interval =     2.91 */
-/* 230 */ 0xc3c10059, /* cps = 126976.00, nrm = 32, interval =     2.78 */
-/* 231 */ 0xc40f0055, /* cps = 132864.00, nrm = 32, interval =     2.66 */
-/* 232 */ 0xc4350052, /* cps = 137728.00, nrm = 32, interval =     2.56 */
-/* 233 */ 0xc46d004e, /* cps = 144896.00, nrm = 32, interval =     2.44 */
-/* 234 */ 0xc499004b, /* cps = 150528.00, nrm = 32, interval =     2.34 */
-/* 235 */ 0xc4cb0048, /* cps = 156928.00, nrm = 32, interval =     2.25 */
-/* 236 */ 0xc4ff0045, /* cps = 163584.00, nrm = 32, interval =     2.16 */
-/* 237 */ 0xc5250043, /* cps = 168448.00, nrm = 32, interval =     2.09 */
-/* 238 */ 0xc5630040, /* cps = 176384.00, nrm = 32, interval =     2.00 */
-/* 239 */ 0xc5a7003d, /* cps = 185088.00, nrm = 32, interval =     1.91 */
-/* 240 */ 0xc5d9003b, /* cps = 191488.00, nrm = 32, interval =     1.84 */
-/* 241 */ 0xc6290038, /* cps = 201728.00, nrm = 32, interval =     1.75 */
-/* 242 */ 0xc6630036, /* cps = 209152.00, nrm = 32, interval =     1.69 */
-/* 243 */ 0xc6a30034, /* cps = 217344.00, nrm = 32, interval =     1.62 */
-/* 244 */ 0xc6e70032, /* cps = 226048.00, nrm = 32, interval =     1.56 */
-/* 245 */ 0xc72f0030, /* cps = 235264.00, nrm = 32, interval =     1.50 */
-/* 246 */ 0xc77f002e, /* cps = 245504.00, nrm = 32, interval =     1.44 */
-/* 247 */ 0xc7d7002c, /* cps = 256768.00, nrm = 32, interval =     1.38 */
-/* 248 */ 0xc81b002a, /* cps = 268800.00, nrm = 32, interval =     1.31 */
-/* 249 */ 0xc84f0028, /* cps = 282112.00, nrm = 32, interval =     1.25 */
-/* 250 */ 0xc86d0027, /* cps = 289792.00, nrm = 32, interval =     1.22 */
-/* 251 */ 0xc8a90025, /* cps = 305152.00, nrm = 32, interval =     1.16 */
-/* 252 */ 0xc8cb0024, /* cps = 313856.00, nrm = 32, interval =     1.12 */
-/* 253 */ 0xc9130022, /* cps = 332288.00, nrm = 32, interval =     1.06 */
-/* 254 */ 0xc9390021, /* cps = 342016.00, nrm = 32, interval =     1.03 */
-/* 255 */ 0xc9630020, /* cps = 352768.00, nrm = 32, interval =     1.00 */
-};
-
-static unsigned char rate_to_log[] =
-{
-/*          1.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.06 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.19 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.31 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.44 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.56 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.69 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.81 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          1.94 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          2.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.12 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.38 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.62 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          3.88 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          4.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          5.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          6.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.25 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          7.75 =>   0 */ 0x00, /* =>     10.02 */
-/*          8.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          8.50 =>   0 */ 0x00, /* =>     10.02 */
-/*          9.00 =>   0 */ 0x00, /* =>     10.02 */
-/*          9.50 =>   0 */ 0x00, /* =>     10.02 */
-/*         10.00 =>   0 */ 0x00, /* =>     10.02 */
-/*         10.50 =>   1 */ 0x01, /* =>     10.42 */
-/*         11.00 =>   2 */ 0x02, /* =>     10.86 */
-/*         11.50 =>   3 */ 0x03, /* =>     11.31 */
-/*         12.00 =>   4 */ 0x04, /* =>     11.78 */
-/*         12.50 =>   5 */ 0x05, /* =>     12.28 */
-/*         13.00 =>   6 */ 0x06, /* =>     12.80 */
-/*         13.50 =>   7 */ 0x07, /* =>     13.33 */
-/*         14.00 =>   8 */ 0x08, /* =>     13.89 */
-/*         14.50 =>   9 */ 0x09, /* =>     14.48 */
-/*         15.00 =>   9 */ 0x09, /* =>     14.48 */
-/*         15.50 =>  10 */ 0x0a, /* =>     15.08 */
-/*         16.00 =>  11 */ 0x0b, /* =>     15.72 */
-/*         17.00 =>  12 */ 0x0c, /* =>     16.38 */
-/*         18.00 =>  14 */ 0x0e, /* =>     17.75 */
-/*         19.00 =>  15 */ 0x0f, /* =>     18.50 */
-/*         20.00 =>  16 */ 0x10, /* =>     19.28 */
-/*         21.00 =>  18 */ 0x12, /* =>     20.94 */
-/*         22.00 =>  19 */ 0x13, /* =>     21.81 */
-/*         23.00 =>  20 */ 0x14, /* =>     22.75 */
-/*         24.00 =>  21 */ 0x15, /* =>     23.69 */
-/*         25.00 =>  22 */ 0x16, /* =>     24.69 */
-/*         26.00 =>  23 */ 0x17, /* =>     25.72 */
-/*         27.00 =>  24 */ 0x18, /* =>     26.81 */
-/*         28.00 =>  25 */ 0x19, /* =>     27.94 */
-/*         29.00 =>  25 */ 0x19, /* =>     27.94 */
-/*         30.00 =>  26 */ 0x1a, /* =>     29.09 */
-/*         31.00 =>  27 */ 0x1b, /* =>     30.31 */
-/*         32.00 =>  28 */ 0x1c, /* =>     31.56 */
-/*         34.00 =>  29 */ 0x1d, /* =>     32.94 */
-/*         36.00 =>  31 */ 0x1f, /* =>     35.69 */
-/*         38.00 =>  32 */ 0x20, /* =>     37.19 */
-/*         40.00 =>  33 */ 0x21, /* =>     38.75 */
-/*         42.00 =>  34 */ 0x22, /* =>     40.38 */
-/*         44.00 =>  36 */ 0x24, /* =>     43.88 */
-/*         46.00 =>  37 */ 0x25, /* =>     45.69 */
-/*         48.00 =>  38 */ 0x26, /* =>     47.62 */
-/*         50.00 =>  39 */ 0x27, /* =>     49.62 */
-/*         52.00 =>  40 */ 0x28, /* =>     51.69 */
-/*         54.00 =>  41 */ 0x29, /* =>     53.88 */
-/*         56.00 =>  41 */ 0x29, /* =>     53.88 */
-/*         58.00 =>  42 */ 0x2a, /* =>     56.12 */
-/*         60.00 =>  43 */ 0x2b, /* =>     58.44 */
-/*         62.00 =>  44 */ 0x2c, /* =>     60.94 */
-/*         64.00 =>  45 */ 0x2d, /* =>     63.50 */
-/*         68.00 =>  46 */ 0x2e, /* =>     66.12 */
-/*         72.00 =>  48 */ 0x30, /* =>     71.88 */
-/*         76.00 =>  49 */ 0x31, /* =>     74.75 */
-/*         80.00 =>  50 */ 0x32, /* =>     78.00 */
-/*         84.00 =>  51 */ 0x33, /* =>     81.25 */
-/*         88.00 =>  52 */ 0x34, /* =>     84.62 */
-/*         92.00 =>  54 */ 0x36, /* =>     91.88 */
-/*         96.00 =>  55 */ 0x37, /* =>     95.75 */
-/*        100.00 =>  56 */ 0x38, /* =>     99.75 */
-/*        104.00 =>  56 */ 0x38, /* =>     99.75 */
-/*        108.00 =>  57 */ 0x39, /* =>    104.00 */
-/*        112.00 =>  58 */ 0x3a, /* =>    108.25 */
-/*        116.00 =>  59 */ 0x3b, /* =>    112.88 */
-/*        120.00 =>  60 */ 0x3c, /* =>    117.50 */
-/*        124.00 =>  61 */ 0x3d, /* =>    122.38 */
-/*        128.00 =>  62 */ 0x3e, /* =>    127.50 */
-/*        136.00 =>  63 */ 0x3f, /* =>    132.75 */
-/*        144.00 =>  64 */ 0x40, /* =>    138.50 */
-/*        152.00 =>  66 */ 0x42, /* =>    150.25 */
-/*        160.00 =>  67 */ 0x43, /* =>    156.75 */
-/*        168.00 =>  68 */ 0x44, /* =>    163.50 */
-/*        176.00 =>  69 */ 0x45, /* =>    170.00 */
-/*        184.00 =>  70 */ 0x46, /* =>    177.25 */
-/*        192.00 =>  71 */ 0x47, /* =>    184.50 */
-/*        200.00 =>  72 */ 0x48, /* =>    192.25 */
-/*        208.00 =>  73 */ 0x49, /* =>    200.25 */
-/*        216.00 =>  74 */ 0x4a, /* =>    208.75 */
-/*        224.00 =>  75 */ 0x4b, /* =>    217.75 */
-/*        232.00 =>  76 */ 0x4c, /* =>    226.75 */
-/*        240.00 =>  77 */ 0x4d, /* =>    236.25 */
-/*        248.00 =>  78 */ 0x4e, /* =>    246.25 */
-/*        256.00 =>  78 */ 0x4e, /* =>    246.25 */
-/*        272.00 =>  80 */ 0x50, /* =>    267.50 */
-/*        288.00 =>  81 */ 0x51, /* =>    278.50 */
-/*        304.00 =>  83 */ 0x53, /* =>    302.00 */
-/*        320.00 =>  84 */ 0x54, /* =>    315.00 */
-/*        336.00 =>  85 */ 0x55, /* =>    328.00 */
-/*        352.00 =>  86 */ 0x56, /* =>    342.00 */
-/*        368.00 =>  87 */ 0x57, /* =>    356.00 */
-/*        384.00 =>  88 */ 0x58, /* =>    371.00 */
-/*        400.00 =>  89 */ 0x59, /* =>    386.50 */
-/*        416.00 =>  90 */ 0x5a, /* =>    403.00 */
-/*        432.00 =>  91 */ 0x5b, /* =>    419.50 */
-/*        448.00 =>  92 */ 0x5c, /* =>    437.50 */
-/*        464.00 =>  93 */ 0x5d, /* =>    455.50 */
-/*        480.00 =>  94 */ 0x5e, /* =>    475.00 */
-/*        496.00 =>  95 */ 0x5f, /* =>    495.00 */
-/*        512.00 =>  95 */ 0x5f, /* =>    495.00 */
-/*        544.00 =>  97 */ 0x61, /* =>    537.00 */
-/*        576.00 =>  98 */ 0x62, /* =>    559.00 */
-/*        608.00 => 100 */ 0x64, /* =>    607.00 */
-/*        640.00 => 101 */ 0x65, /* =>    632.00 */
-/*        672.00 => 102 */ 0x66, /* =>    660.00 */
-/*        704.00 => 103 */ 0x67, /* =>    687.00 */
-/*        736.00 => 104 */ 0x68, /* =>    716.00 */
-/*        768.00 => 105 */ 0x69, /* =>    746.00 */
-/*        800.00 => 106 */ 0x6a, /* =>    777.00 */
-/*        832.00 => 107 */ 0x6b, /* =>    810.00 */
-/*        864.00 => 108 */ 0x6c, /* =>    843.00 */
-/*        896.00 => 109 */ 0x6d, /* =>    879.00 */
-/*        928.00 => 110 */ 0x6e, /* =>    916.00 */
-/*        960.00 => 111 */ 0x6f, /* =>    954.00 */
-/*        992.00 => 111 */ 0x6f, /* =>    954.00 */
-/*       1024.00 => 112 */ 0x70, /* =>    994.00 */
-/*       1088.00 => 114 */ 0x72, /* =>   1080.00 */
-/*       1152.00 => 115 */ 0x73, /* =>   1124.00 */
-/*       1216.00 => 116 */ 0x74, /* =>   1172.00 */
-/*       1280.00 => 118 */ 0x76, /* =>   1272.00 */
-/*       1344.00 => 119 */ 0x77, /* =>   1326.00 */
-/*       1408.00 => 120 */ 0x78, /* =>   1382.00 */
-/*       1472.00 => 121 */ 0x79, /* =>   1440.00 */
-/*       1536.00 => 122 */ 0x7a, /* =>   1498.00 */
-/*       1600.00 => 123 */ 0x7b, /* =>   1562.00 */
-/*       1664.00 => 124 */ 0x7c, /* =>   1628.00 */
-/*       1728.00 => 125 */ 0x7d, /* =>   1696.00 */
-/*       1792.00 => 126 */ 0x7e, /* =>   1768.00 */
-/*       1856.00 => 127 */ 0x7f, /* =>   1842.00 */
-/*       1920.00 => 128 */ 0x80, /* =>   1918.00 */
-/*       1984.00 => 128 */ 0x80, /* =>   1918.00 */
-/*       2048.00 => 129 */ 0x81, /* =>   2000.00 */
-/*       2176.00 => 131 */ 0x83, /* =>   2168.00 */
-/*       2304.00 => 132 */ 0x84, /* =>   2264.00 */
-/*       2432.00 => 133 */ 0x85, /* =>   2356.00 */
-/*       2560.00 => 135 */ 0x87, /* =>   2556.00 */
-/*       2688.00 => 136 */ 0x88, /* =>   2664.00 */
-/*       2816.00 => 137 */ 0x89, /* =>   2776.00 */
-/*       2944.00 => 138 */ 0x8a, /* =>   2892.00 */
-/*       3072.00 => 139 */ 0x8b, /* =>   3012.00 */
-/*       3200.00 => 140 */ 0x8c, /* =>   3140.00 */
-/*       3328.00 => 141 */ 0x8d, /* =>   3272.00 */
-/*       3456.00 => 142 */ 0x8e, /* =>   3412.00 */
-/*       3584.00 => 143 */ 0x8f, /* =>   3552.00 */
-/*       3712.00 => 144 */ 0x90, /* =>   3700.00 */
-/*       3840.00 => 144 */ 0x90, /* =>   3700.00 */
-/*       3968.00 => 145 */ 0x91, /* =>   3860.00 */
-/*       4096.00 => 146 */ 0x92, /* =>   4016.00 */
-/*       4352.00 => 147 */ 0x93, /* =>   4184.00 */
-/*       4608.00 => 149 */ 0x95, /* =>   4544.00 */
-/*       4864.00 => 150 */ 0x96, /* =>   4736.00 */
-/*       5120.00 => 151 */ 0x97, /* =>   4936.00 */
-/*       5376.00 => 153 */ 0x99, /* =>   5360.00 */
-/*       5632.00 => 154 */ 0x9a, /* =>   5584.00 */
-/*       5888.00 => 155 */ 0x9b, /* =>   5816.00 */
-/*       6144.00 => 156 */ 0x9c, /* =>   6056.00 */
-/*       6400.00 => 157 */ 0x9d, /* =>   6312.00 */
-/*       6656.00 => 158 */ 0x9e, /* =>   6576.00 */
-/*       6912.00 => 159 */ 0x9f, /* =>   6856.00 */
-/*       7168.00 => 160 */ 0xa0, /* =>   7144.00 */
-/*       7424.00 => 160 */ 0xa0, /* =>   7144.00 */
-/*       7680.00 => 161 */ 0xa1, /* =>   7440.00 */
-/*       7936.00 => 162 */ 0xa2, /* =>   7752.00 */
-/*       8192.00 => 163 */ 0xa3, /* =>   8080.00 */
-/*       8704.00 => 164 */ 0xa4, /* =>   8416.00 */
-/*       9216.00 => 166 */ 0xa6, /* =>   9136.00 */
-/*       9728.00 => 167 */ 0xa7, /* =>   9520.00 */
-/*      10240.00 => 168 */ 0xa8, /* =>   9920.00 */
-/*      10752.00 => 169 */ 0xa9, /* =>  10336.00 */
-/*      11264.00 => 171 */ 0xab, /* =>  11216.00 */
-/*      11776.00 => 172 */ 0xac, /* =>  11680.00 */
-/*      12288.00 => 173 */ 0xad, /* =>  12176.00 */
-/*      12800.00 => 174 */ 0xae, /* =>  12688.00 */
-/*      13312.00 => 175 */ 0xaf, /* =>  13216.00 */
-/*      13824.00 => 176 */ 0xb0, /* =>  13776.00 */
-/*      14336.00 => 176 */ 0xb0, /* =>  13776.00 */
-/*      14848.00 => 177 */ 0xb1, /* =>  14352.00 */
-/*      15360.00 => 178 */ 0xb2, /* =>  14960.00 */
-/*      15872.00 => 179 */ 0xb3, /* =>  15584.00 */
-/*      16384.00 => 180 */ 0xb4, /* =>  16224.00 */
-/*      17408.00 => 181 */ 0xb5, /* =>  16896.00 */
-/*      18432.00 => 183 */ 0xb7, /* =>  18368.00 */
-/*      19456.00 => 184 */ 0xb8, /* =>  19136.00 */
-/*      20480.00 => 185 */ 0xb9, /* =>  19904.00 */
-/*      21504.00 => 186 */ 0xba, /* =>  20768.00 */
-/*      22528.00 => 187 */ 0xbb, /* =>  21632.00 */
-/*      23552.00 => 189 */ 0xbd, /* =>  23488.00 */
-/*      24576.00 => 190 */ 0xbe, /* =>  24512.00 */
-/*      25600.00 => 191 */ 0xbf, /* =>  25504.00 */
-/*      26624.00 => 192 */ 0xc0, /* =>  26592.00 */
-/*      27648.00 => 192 */ 0xc0, /* =>  26592.00 */
-/*      28672.00 => 193 */ 0xc1, /* =>  27680.00 */
-/*      29696.00 => 194 */ 0xc2, /* =>  28896.00 */
-/*      30720.00 => 195 */ 0xc3, /* =>  30048.00 */
-/*      31744.00 => 196 */ 0xc4, /* =>  31392.00 */
-/*      32768.00 => 197 */ 0xc5, /* =>  32640.00 */
-/*      34816.00 => 198 */ 0xc6, /* =>  33984.00 */
-/*      36864.00 => 199 */ 0xc7, /* =>  35392.00 */
-/*      38912.00 => 201 */ 0xc9, /* =>  38528.00 */
-/*      40960.00 => 202 */ 0xca, /* =>  40064.00 */
-/*      43008.00 => 203 */ 0xcb, /* =>  41856.00 */
-/*      45056.00 => 204 */ 0xcc, /* =>  43584.00 */
-/*      47104.00 => 205 */ 0xcd, /* =>  45376.00 */
-/*      49152.00 => 206 */ 0xce, /* =>  47232.00 */
-/*      51200.00 => 207 */ 0xcf, /* =>  49344.00 */
-/*      53248.00 => 208 */ 0xd0, /* =>  51328.00 */
-/*      55296.00 => 209 */ 0xd1, /* =>  53504.00 */
-/*      57344.00 => 210 */ 0xd2, /* =>  55616.00 */
-/*      59392.00 => 211 */ 0xd3, /* =>  58240.00 */
-/*      61440.00 => 212 */ 0xd4, /* =>  60416.00 */
-/*      63488.00 => 213 */ 0xd5, /* =>  63104.00 */
-/*      65536.00 => 213 */ 0xd5, /* =>  63104.00 */
-/*      69632.00 => 215 */ 0xd7, /* =>  68480.00 */
-/*      73728.00 => 216 */ 0xd8, /* =>  71424.00 */
-/*      77824.00 => 218 */ 0xda, /* =>  77312.00 */
-/*      81920.00 => 219 */ 0xdb, /* =>  80640.00 */
-/*      86016.00 => 220 */ 0xdc, /* =>  84224.00 */
-/*      90112.00 => 221 */ 0xdd, /* =>  87552.00 */
-/*      94208.00 => 222 */ 0xde, /* =>  91136.00 */
-/*      98304.00 => 223 */ 0xdf, /* =>  94976.00 */
-/*     102400.00 => 224 */ 0xe0, /* =>  99072.00 */
-/*     106496.00 => 225 */ 0xe1, /* => 103680.00 */
-/*     110592.00 => 226 */ 0xe2, /* => 107520.00 */
-/*     114688.00 => 227 */ 0xe3, /* => 111872.00 */
-/*     118784.00 => 228 */ 0xe4, /* => 117632.00 */
-/*     122880.00 => 229 */ 0xe5, /* => 121472.00 */
-/*     126976.00 => 229 */ 0xe5, /* => 121472.00 */
-/*     131072.00 => 230 */ 0xe6, /* => 126976.00 */
-/*     139264.00 => 232 */ 0xe8, /* => 137728.00 */
-/*     147456.00 => 233 */ 0xe9, /* => 144896.00 */
-/*     155648.00 => 234 */ 0xea, /* => 150528.00 */
-/*     163840.00 => 236 */ 0xec, /* => 163584.00 */
-/*     172032.00 => 237 */ 0xed, /* => 168448.00 */
-/*     180224.00 => 238 */ 0xee, /* => 176384.00 */
-/*     188416.00 => 239 */ 0xef, /* => 185088.00 */
-/*     196608.00 => 240 */ 0xf0, /* => 191488.00 */
-/*     204800.00 => 241 */ 0xf1, /* => 201728.00 */
-/*     212992.00 => 242 */ 0xf2, /* => 209152.00 */
-/*     221184.00 => 243 */ 0xf3, /* => 217344.00 */
-/*     229376.00 => 244 */ 0xf4, /* => 226048.00 */
-/*     237568.00 => 245 */ 0xf5, /* => 235264.00 */
-/*     245760.00 => 246 */ 0xf6, /* => 245504.00 */
-/*     253952.00 => 246 */ 0xf6, /* => 245504.00 */
-/*     262144.00 => 247 */ 0xf7, /* => 256768.00 */
-/*     278528.00 => 248 */ 0xf8, /* => 268800.00 */
-/*     294912.00 => 250 */ 0xfa, /* => 289792.00 */
-/*     311296.00 => 251 */ 0xfb, /* => 305152.00 */
-/*     327680.00 => 252 */ 0xfc, /* => 313856.00 */
-/*     344064.00 => 254 */ 0xfe, /* => 342016.00 */
-/*     360448.00 => 255 */ 0xff, /* => 352768.00 */
-/*     376832.00 => 255 */ 0xff, /* => 352768.00 */
-/*     393216.00 => 255 */ 0xff, /* => 352768.00 */
-/*     409600.00 => 255 */ 0xff, /* => 352768.00 */
-/*     425984.00 => 255 */ 0xff, /* => 352768.00 */
-/*     442368.00 => 255 */ 0xff, /* => 352768.00 */
-/*     458752.00 => 255 */ 0xff, /* => 352768.00 */
-/*     475136.00 => 255 */ 0xff, /* => 352768.00 */
-/*     491520.00 => 255 */ 0xff, /* => 352768.00 */
-/*     507904.00 => 255 */ 0xff, /* => 352768.00 */
-/*     524288.00 => 255 */ 0xff, /* => 352768.00 */
-/*     557056.00 => 255 */ 0xff, /* => 352768.00 */
-/*     589824.00 => 255 */ 0xff, /* => 352768.00 */
-/*     622592.00 => 255 */ 0xff, /* => 352768.00 */
-/*     655360.00 => 255 */ 0xff, /* => 352768.00 */
-/*     688128.00 => 255 */ 0xff, /* => 352768.00 */
-/*     720896.00 => 255 */ 0xff, /* => 352768.00 */
-/*     753664.00 => 255 */ 0xff, /* => 352768.00 */
-/*     786432.00 => 255 */ 0xff, /* => 352768.00 */
-/*     819200.00 => 255 */ 0xff, /* => 352768.00 */
-/*     851968.00 => 255 */ 0xff, /* => 352768.00 */
-/*     884736.00 => 255 */ 0xff, /* => 352768.00 */
-/*     917504.00 => 255 */ 0xff, /* => 352768.00 */
-/*     950272.00 => 255 */ 0xff, /* => 352768.00 */
-/*     983040.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1015808.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1048576.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1114112.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1179648.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1245184.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1310720.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1376256.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1441792.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1507328.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1572864.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1638400.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1703936.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1769472.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1835008.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1900544.00 => 255 */ 0xff, /* => 352768.00 */
-/*    1966080.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2031616.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2097152.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2228224.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2359296.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2490368.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2621440.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2752512.00 => 255 */ 0xff, /* => 352768.00 */
-/*    2883584.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3014656.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3145728.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3276800.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3407872.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3538944.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3670016.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3801088.00 => 255 */ 0xff, /* => 352768.00 */
-/*    3932160.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4063232.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4194304.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4456448.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4718592.00 => 255 */ 0xff, /* => 352768.00 */
-/*    4980736.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5242880.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5505024.00 => 255 */ 0xff, /* => 352768.00 */
-/*    5767168.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6029312.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6291456.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6553600.00 => 255 */ 0xff, /* => 352768.00 */
-/*    6815744.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7077888.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7340032.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7602176.00 => 255 */ 0xff, /* => 352768.00 */
-/*    7864320.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8126464.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8388608.00 => 255 */ 0xff, /* => 352768.00 */
-/*    8912896.00 => 255 */ 0xff, /* => 352768.00 */
-/*    9437184.00 => 255 */ 0xff, /* => 352768.00 */
-/*    9961472.00 => 255 */ 0xff, /* => 352768.00 */
-/*   10485760.00 => 255 */ 0xff, /* => 352768.00 */
-/*   11010048.00 => 255 */ 0xff, /* => 352768.00 */
-/*   11534336.00 => 255 */ 0xff, /* => 352768.00 */
-/*   12058624.00 => 255 */ 0xff, /* => 352768.00 */
-/*   12582912.00 => 255 */ 0xff, /* => 352768.00 */
-/*   13107200.00 => 255 */ 0xff, /* => 352768.00 */
-/*   13631488.00 => 255 */ 0xff, /* => 352768.00 */
-/*   14155776.00 => 255 */ 0xff, /* => 352768.00 */
-/*   14680064.00 => 255 */ 0xff, /* => 352768.00 */
-/*   15204352.00 => 255 */ 0xff, /* => 352768.00 */
-/*   15728640.00 => 255 */ 0xff, /* => 352768.00 */
-/*   16252928.00 => 255 */ 0xff, /* => 352768.00 */
-/*   16777216.00 => 255 */ 0xff, /* => 352768.00 */
-/*   17825792.00 => 255 */ 0xff, /* => 352768.00 */
-/*   18874368.00 => 255 */ 0xff, /* => 352768.00 */
-/*   19922944.00 => 255 */ 0xff, /* => 352768.00 */
-/*   20971520.00 => 255 */ 0xff, /* => 352768.00 */
-/*   22020096.00 => 255 */ 0xff, /* => 352768.00 */
-/*   23068672.00 => 255 */ 0xff, /* => 352768.00 */
-/*   24117248.00 => 255 */ 0xff, /* => 352768.00 */
-/*   25165824.00 => 255 */ 0xff, /* => 352768.00 */
-/*   26214400.00 => 255 */ 0xff, /* => 352768.00 */
-/*   27262976.00 => 255 */ 0xff, /* => 352768.00 */
-/*   28311552.00 => 255 */ 0xff, /* => 352768.00 */
-/*   29360128.00 => 255 */ 0xff, /* => 352768.00 */
-/*   30408704.00 => 255 */ 0xff, /* => 352768.00 */
-/*   31457280.00 => 255 */ 0xff, /* => 352768.00 */
-/*   32505856.00 => 255 */ 0xff, /* => 352768.00 */
-/*   33554432.00 => 255 */ 0xff, /* => 352768.00 */
-/*   35651584.00 => 255 */ 0xff, /* => 352768.00 */
-/*   37748736.00 => 255 */ 0xff, /* => 352768.00 */
-/*   39845888.00 => 255 */ 0xff, /* => 352768.00 */
-/*   41943040.00 => 255 */ 0xff, /* => 352768.00 */
-/*   44040192.00 => 255 */ 0xff, /* => 352768.00 */
-/*   46137344.00 => 255 */ 0xff, /* => 352768.00 */
-/*   48234496.00 => 255 */ 0xff, /* => 352768.00 */
-/*   50331648.00 => 255 */ 0xff, /* => 352768.00 */
-/*   52428800.00 => 255 */ 0xff, /* => 352768.00 */
-/*   54525952.00 => 255 */ 0xff, /* => 352768.00 */
-/*   56623104.00 => 255 */ 0xff, /* => 352768.00 */
-/*   58720256.00 => 255 */ 0xff, /* => 352768.00 */
-/*   60817408.00 => 255 */ 0xff, /* => 352768.00 */
-/*   62914560.00 => 255 */ 0xff, /* => 352768.00 */
-/*   65011712.00 => 255 */ 0xff, /* => 352768.00 */
-/*   67108864.00 => 255 */ 0xff, /* => 352768.00 */
-/*   71303168.00 => 255 */ 0xff, /* => 352768.00 */
-/*   75497472.00 => 255 */ 0xff, /* => 352768.00 */
-/*   79691776.00 => 255 */ 0xff, /* => 352768.00 */
-/*   83886080.00 => 255 */ 0xff, /* => 352768.00 */
-/*   88080384.00 => 255 */ 0xff, /* => 352768.00 */
-/*   92274688.00 => 255 */ 0xff, /* => 352768.00 */
-/*   96468992.00 => 255 */ 0xff, /* => 352768.00 */
-/*  100663296.00 => 255 */ 0xff, /* => 352768.00 */
-/*  104857600.00 => 255 */ 0xff, /* => 352768.00 */
-/*  109051904.00 => 255 */ 0xff, /* => 352768.00 */
-/*  113246208.00 => 255 */ 0xff, /* => 352768.00 */
-/*  117440512.00 => 255 */ 0xff, /* => 352768.00 */
-/*  121634816.00 => 255 */ 0xff, /* => 352768.00 */
-/*  125829120.00 => 255 */ 0xff, /* => 352768.00 */
-/*  130023424.00 => 255 */ 0xff, /* => 352768.00 */
-/*  134217728.00 => 255 */ 0xff, /* => 352768.00 */
-/*  142606336.00 => 255 */ 0xff, /* => 352768.00 */
-/*  150994944.00 => 255 */ 0xff, /* => 352768.00 */
-/*  159383552.00 => 255 */ 0xff, /* => 352768.00 */
-/*  167772160.00 => 255 */ 0xff, /* => 352768.00 */
-/*  176160768.00 => 255 */ 0xff, /* => 352768.00 */
-/*  184549376.00 => 255 */ 0xff, /* => 352768.00 */
-/*  192937984.00 => 255 */ 0xff, /* => 352768.00 */
-/*  201326592.00 => 255 */ 0xff, /* => 352768.00 */
-/*  209715200.00 => 255 */ 0xff, /* => 352768.00 */
-/*  218103808.00 => 255 */ 0xff, /* => 352768.00 */
-/*  226492416.00 => 255 */ 0xff, /* => 352768.00 */
-/*  234881024.00 => 255 */ 0xff, /* => 352768.00 */
-/*  243269632.00 => 255 */ 0xff, /* => 352768.00 */
-/*  251658240.00 => 255 */ 0xff, /* => 352768.00 */
-/*  260046848.00 => 255 */ 0xff, /* => 352768.00 */
-/*  268435456.00 => 255 */ 0xff, /* => 352768.00 */
-/*  285212672.00 => 255 */ 0xff, /* => 352768.00 */
-/*  301989888.00 => 255 */ 0xff, /* => 352768.00 */
-/*  318767104.00 => 255 */ 0xff, /* => 352768.00 */
-/*  335544320.00 => 255 */ 0xff, /* => 352768.00 */
-/*  352321536.00 => 255 */ 0xff, /* => 352768.00 */
-/*  369098752.00 => 255 */ 0xff, /* => 352768.00 */
-/*  385875968.00 => 255 */ 0xff, /* => 352768.00 */
-/*  402653184.00 => 255 */ 0xff, /* => 352768.00 */
-/*  419430400.00 => 255 */ 0xff, /* => 352768.00 */
-/*  436207616.00 => 255 */ 0xff, /* => 352768.00 */
-/*  452984832.00 => 255 */ 0xff, /* => 352768.00 */
-/*  469762048.00 => 255 */ 0xff, /* => 352768.00 */
-/*  486539264.00 => 255 */ 0xff, /* => 352768.00 */
-/*  503316480.00 => 255 */ 0xff, /* => 352768.00 */
-/*  520093696.00 => 255 */ 0xff, /* => 352768.00 */
-/*  536870912.00 => 255 */ 0xff, /* => 352768.00 */
-/*  570425344.00 => 255 */ 0xff, /* => 352768.00 */
-/*  603979776.00 => 255 */ 0xff, /* => 352768.00 */
-/*  637534208.00 => 255 */ 0xff, /* => 352768.00 */
-/*  671088640.00 => 255 */ 0xff, /* => 352768.00 */
-/*  704643072.00 => 255 */ 0xff, /* => 352768.00 */
-/*  738197504.00 => 255 */ 0xff, /* => 352768.00 */
-/*  771751936.00 => 255 */ 0xff, /* => 352768.00 */
-/*  805306368.00 => 255 */ 0xff, /* => 352768.00 */
-/*  838860800.00 => 255 */ 0xff, /* => 352768.00 */
-/*  872415232.00 => 255 */ 0xff, /* => 352768.00 */
-/*  905969664.00 => 255 */ 0xff, /* => 352768.00 */
-/*  939524096.00 => 255 */ 0xff, /* => 352768.00 */
-/*  973078528.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1006632960.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1040187392.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1073741824.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1140850688.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1207959552.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1275068416.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1342177280.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1409286144.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1476395008.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1543503872.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1610612736.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1677721600.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1744830464.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1811939328.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1879048192.00 => 255 */ 0xff, /* => 352768.00 */
-/* 1946157056.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2013265920.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2080374784.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2147483648.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2281701376.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2415919104.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2550136832.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2684354560.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2818572288.00 => 255 */ 0xff, /* => 352768.00 */
-/* 2952790016.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3087007744.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3221225472.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3355443200.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3489660928.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3623878656.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3758096384.00 => 255 */ 0xff, /* => 352768.00 */
-/* 3892314112.00 => 255 */ 0xff, /* => 352768.00 */
-/* 4026531840.00 => 255 */ 0xff, /* => 352768.00 */
-/* 4160749568.00 => 255 */ 0xff, /* => 352768.00 */
-};
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
deleted file mode 100644
index 0d38e93..0000000
--- a/drivers/atm/iphase.c
+++ /dev/null
@@ -1,3283 +0,0 @@
-/******************************************************************************
-         iphase.c: Device driver for Interphase ATM PCI adapter cards 
-                    Author: Peter Wang  <pwang@iphase.com>            
-		   Some fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-                   Interphase Corporation  <www.iphase.com>           
-                               Version: 1.0                           
-*******************************************************************************
-      
-      This software may be used and distributed according to the terms
-      of the GNU General Public License (GPL), incorporated herein by reference.
-      Drivers based on this skeleton fall under the GPL and must retain
-      the authorship (implicit copyright) notice.
-
-      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.
-      
-      Modified from an incomplete driver for Interphase 5575 1KVC 1M card which 
-      was originally written by Monalisa Agrawal at UNH. Now this driver 
-      supports a variety of varients of Interphase ATM PCI (i)Chip adapter 
-      card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) 
-      in terms of PHY type, the size of control memory and the size of 
-      packet memory. The following are the change log and history:
-     
-          Bugfix the Mona's UBR driver.
-          Modify the basic memory allocation and dma logic.
-          Port the driver to the latest kernel from 2.0.46.
-          Complete the ABR logic of the driver, and added the ABR work-
-              around for the hardware anormalies.
-          Add the CBR support.
-	  Add the flow control logic to the driver to allow rate-limit VC.
-          Add 4K VC support to the board with 512K control memory.
-          Add the support of all the variants of the Interphase ATM PCI 
-          (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
-          (25M UTP25) and x531 (DS3 and E3).
-          Add SMP support.
-
-      Support and updates available at: ftp://ftp.iphase.com/pub/atm
-
-*******************************************************************************/
-
-#include <linux/module.h>  
-#include <linux/kernel.h>  
-#include <linux/mm.h>  
-#include <linux/pci.h>  
-#include <linux/errno.h>  
-#include <linux/atm.h>  
-#include <linux/atmdev.h>  
-#include <linux/ctype.h>
-#include <linux/sonet.h>  
-#include <linux/skbuff.h>  
-#include <linux/time.h>  
-#include <linux/delay.h>  
-#include <linux/uio.h>  
-#include <linux/init.h>  
-#include <linux/interrupt.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <asm/io.h>  
-#include <linux/atomic.h>
-#include <linux/uaccess.h>  
-#include <asm/string.h>  
-#include <asm/byteorder.h>  
-#include <linux/vmalloc.h>
-#include <linux/jiffies.h>
-#include <linux/nospec.h>
-#include "iphase.h"		  
-#include "suni.h"		  
-#define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
-
-#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
-
-static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr);
-static void desc_dbg(IADEV *iadev);
-
-static IADEV *ia_dev[8];
-static struct atm_dev *_ia_dev[8];
-static int iadev_count;
-static void ia_led_timer(struct timer_list *unused);
-static DEFINE_TIMER(ia_timer, ia_led_timer);
-static int IA_TX_BUF = DFL_TX_BUFFERS, IA_TX_BUF_SZ = DFL_TX_BUF_SZ;
-static int IA_RX_BUF = DFL_RX_BUFFERS, IA_RX_BUF_SZ = DFL_RX_BUF_SZ;
-static uint IADebugFlag = /* IF_IADBG_ERR | IF_IADBG_CBR| IF_IADBG_INIT_ADAPTER
-            |IF_IADBG_ABR | IF_IADBG_EVENT*/ 0; 
-
-module_param(IA_TX_BUF, int, 0);
-module_param(IA_TX_BUF_SZ, int, 0);
-module_param(IA_RX_BUF, int, 0);
-module_param(IA_RX_BUF_SZ, int, 0);
-module_param(IADebugFlag, uint, 0644);
-
-MODULE_DESCRIPTION("Driver for Interphase ATM PCI NICs");
-MODULE_LICENSE("GPL");
-
-/**************************** IA_LIB **********************************/
-
-static void ia_init_rtn_q (IARTN_Q *que) 
-{ 
-   que->next = NULL; 
-   que->tail = NULL; 
-}
-
-static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data) 
-{
-   data->next = NULL;
-   if (que->next == NULL) 
-      que->next = que->tail = data;
-   else {
-      data->next = que->next;
-      que->next = data;
-   } 
-   return;
-}
-
-static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) {
-   IARTN_Q *entry = kmalloc_obj(*entry, GFP_ATOMIC);
-   if (!entry)
-      return -ENOMEM;
-   entry->data = data;
-   entry->next = NULL;
-   if (que->next == NULL) 
-      que->next = que->tail = entry;
-   else {
-      que->tail->next = entry;
-      que->tail = que->tail->next;
-   }      
-   return 1;
-}
-
-static IARTN_Q * ia_deque_rtn_q (IARTN_Q *que) {
-   IARTN_Q *tmpdata;
-   if (que->next == NULL)
-      return NULL;
-   tmpdata = que->next;
-   if ( que->next == que->tail)  
-      que->next = que->tail = NULL;
-   else 
-      que->next = que->next->next;
-   return tmpdata;
-}
-
-static void ia_hack_tcq(IADEV *dev) {
-
-  u_short 		desc1;
-  u_short		tcq_wr;
-  struct ia_vcc         *iavcc_r = NULL; 
-
-  tcq_wr = readl(dev->seg_reg+TCQ_WR_PTR) & 0xffff;
-  while (dev->host_tcq_wr != tcq_wr) {
-     desc1 = *(u_short *)(dev->seg_ram + dev->host_tcq_wr);
-     if (!desc1) ;
-     else if (!dev->desc_tbl[desc1 -1].timestamp) {
-        IF_ABR(printk(" Desc %d is reset at %ld\n", desc1 -1, jiffies);)
-        *(u_short *) (dev->seg_ram + dev->host_tcq_wr) = 0;
-     }                                 
-     else if (dev->desc_tbl[desc1 -1].timestamp) {
-        if (!(iavcc_r = dev->desc_tbl[desc1 -1].iavcc)) { 
-           printk("IA: Fatal err in get_desc\n");
-           continue;
-        }
-        iavcc_r->vc_desc_cnt--;
-        dev->desc_tbl[desc1 -1].timestamp = 0;
-        IF_EVENT(printk("ia_hack: return_q skb = 0x%p desc = %d\n",
-                                   dev->desc_tbl[desc1 -1].txskb, desc1);)
-        if (iavcc_r->pcr < dev->rate_limit) {
-           IA_SKB_STATE (dev->desc_tbl[desc1-1].txskb) |= IA_TX_DONE;
-           if (ia_enque_rtn_q(&dev->tx_return_q, dev->desc_tbl[desc1 -1]) < 0)
-              printk("ia_hack_tcq: No memory available\n");
-        } 
-        dev->desc_tbl[desc1 -1].iavcc = NULL;
-        dev->desc_tbl[desc1 -1].txskb = NULL;
-     }
-     dev->host_tcq_wr += 2;
-     if (dev->host_tcq_wr > dev->ffL.tcq_ed) 
-        dev->host_tcq_wr = dev->ffL.tcq_st;
-  }
-} /* ia_hack_tcq */
-
-static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) {
-  u_short 		desc_num, i;
-  struct ia_vcc         *iavcc_r = NULL; 
-  unsigned long delta;
-  static unsigned long timer = 0;
-  int ltimeout;
-
-  ia_hack_tcq (dev);
-  if((time_after(jiffies,timer+50)) || ((dev->ffL.tcq_rd==dev->host_tcq_wr))) {
-     timer = jiffies; 
-     i=0;
-     while (i < dev->num_tx_desc) {
-        if (!dev->desc_tbl[i].timestamp) {
-           i++;
-           continue;
-        }
-        ltimeout = dev->desc_tbl[i].iavcc->ltimeout; 
-        delta = jiffies - dev->desc_tbl[i].timestamp;
-        if (delta >= ltimeout) {
-           IF_ABR(printk("RECOVER run!! desc_tbl %d = %d  delta = %ld, time = %ld\n", i,dev->desc_tbl[i].timestamp, delta, jiffies);)
-           if (dev->ffL.tcq_rd == dev->ffL.tcq_st) 
-              dev->ffL.tcq_rd =  dev->ffL.tcq_ed;
-           else 
-              dev->ffL.tcq_rd -= 2;
-           *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd) = i+1;
-           if (!dev->desc_tbl[i].txskb || !(iavcc_r = dev->desc_tbl[i].iavcc))
-              printk("Fatal err, desc table vcc or skb is NULL\n");
-           else 
-              iavcc_r->vc_desc_cnt--;
-           dev->desc_tbl[i].timestamp = 0;
-           dev->desc_tbl[i].iavcc = NULL;
-           dev->desc_tbl[i].txskb = NULL;
-        }
-        i++;
-     } /* while */
-  }
-  if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
-     return 0xFFFF;
-    
-  /* Get the next available descriptor number from TCQ */
-  desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
-
-  while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) {
-     dev->ffL.tcq_rd += 2;
-     if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) 
-	dev->ffL.tcq_rd = dev->ffL.tcq_st;
-     if (dev->ffL.tcq_rd == dev->host_tcq_wr) 
-        return 0xFFFF; 
-     desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd);
-  }
-
-  /* get system time */
-  dev->desc_tbl[desc_num -1].timestamp = jiffies;
-  return desc_num;
-}
-
-static void clear_lockup (struct atm_vcc *vcc, IADEV *dev) {
-  u_char          	foundLockUp;
-  vcstatus_t		*vcstatus;
-  u_short               *shd_tbl;
-  u_short               tempCellSlot, tempFract;
-  struct main_vc *abr_vc = (struct main_vc *)dev->MAIN_VC_TABLE_ADDR;
-  struct ext_vc *eabr_vc = (struct ext_vc *)dev->EXT_VC_TABLE_ADDR;
-  u_int  i;
-
-  if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-     vcstatus = (vcstatus_t *) &(dev->testTable[vcc->vci]->vc_status);
-     vcstatus->cnt++;
-     foundLockUp = 0;
-     if( vcstatus->cnt == 0x05 ) {
-        abr_vc += vcc->vci;
-	eabr_vc += vcc->vci;
-	if( eabr_vc->last_desc ) {
-	   if( (abr_vc->status & 0x07) == ABR_STATE /* 0x2 */ ) {
-              /* Wait for 10 Micro sec */
-              udelay(10);
-	      if ((eabr_vc->last_desc)&&((abr_vc->status & 0x07)==ABR_STATE))
-		 foundLockUp = 1;
-           }
-	   else {
-	      tempCellSlot = abr_vc->last_cell_slot;
-              tempFract    = abr_vc->fraction;
-              if((tempCellSlot == dev->testTable[vcc->vci]->lastTime)
-                         && (tempFract == dev->testTable[vcc->vci]->fract))
-	         foundLockUp = 1; 		    
-              dev->testTable[vcc->vci]->lastTime = tempCellSlot;   
-              dev->testTable[vcc->vci]->fract = tempFract; 
-	   } 	    
-        } /* last descriptor */	 	   
-        vcstatus->cnt = 0;     	
-     } /* vcstatus->cnt */
-	
-     if (foundLockUp) {
-        IF_ABR(printk("LOCK UP found\n");) 
-	writew(0xFFFD, dev->seg_reg+MODE_REG_0);
-        /* Wait for 10 Micro sec */
-        udelay(10); 
-        abr_vc->status &= 0xFFF8;
-        abr_vc->status |= 0x0001;  /* state is idle */
-	shd_tbl = (u_short *)dev->ABR_SCHED_TABLE_ADDR;                
-	for( i = 0; ((i < dev->num_vc) && (shd_tbl[i])); i++ );
-	if (i < dev->num_vc)
-           shd_tbl[i] = vcc->vci;
-        else
-           IF_ERR(printk("ABR Seg. may not continue on VC %x\n",vcc->vci);)
-        writew(T_ONLINE, dev->seg_reg+MODE_REG_0);
-        writew(~(TRANSMIT_DONE|TCQ_NOT_EMPTY), dev->seg_reg+SEG_MASK_REG);
-        writew(TRANSMIT_DONE, dev->seg_reg+SEG_INTR_STATUS_REG);       
-	vcstatus->cnt = 0;
-     } /* foundLockUp */
-
-  } /* if an ABR VC */
-
-
-}
- 
-/*
-** Conversion of 24-bit cellrate (cells/sec) to 16-bit floating point format.
-**
-**  +----+----+------------------+-------------------------------+
-**  |  R | NZ |  5-bit exponent  |        9-bit mantissa         |
-**  +----+----+------------------+-------------------------------+
-** 
-**    R = reserved (written as 0)
-**    NZ = 0 if 0 cells/sec; 1 otherwise
-**
-**    if NZ = 1, rate = 1.mmmmmmmmm x 2^(eeeee) cells/sec
-*/
-static u16
-cellrate_to_float(u32 cr)
-{
-
-#define	NZ 		0x4000
-#define	M_BITS		9		/* Number of bits in mantissa */
-#define	E_BITS		5		/* Number of bits in exponent */
-#define	M_MASK		0x1ff		
-#define	E_MASK		0x1f
-  u16   flot;
-  u32	tmp = cr & 0x00ffffff;
-  int 	i   = 0;
-  if (cr == 0)
-     return 0;
-  while (tmp != 1) {
-     tmp >>= 1;
-     i++;
-  }
-  if (i == M_BITS)
-     flot = NZ | (i << M_BITS) | (cr & M_MASK);
-  else if (i < M_BITS)
-     flot = NZ | (i << M_BITS) | ((cr << (M_BITS - i)) & M_MASK);
-  else
-     flot = NZ | (i << M_BITS) | ((cr >> (i - M_BITS)) & M_MASK);
-  return flot;
-}
-
-#if 0
-/*
-** Conversion of 16-bit floating point format to 24-bit cellrate (cells/sec).
-*/
-static u32
-float_to_cellrate(u16 rate)
-{
-  u32   exp, mantissa, cps;
-  if ((rate & NZ) == 0)
-     return 0;
-  exp = (rate >> M_BITS) & E_MASK;
-  mantissa = rate & M_MASK;
-  if (exp == 0)
-     return 1;
-  cps = (1 << M_BITS) | mantissa;
-  if (exp == M_BITS)
-     cps = cps;
-  else if (exp > M_BITS)
-     cps <<= (exp - M_BITS);
-  else
-     cps >>= (M_BITS - exp);
-  return cps;
-}
-#endif 
-
-static void init_abr_vc (IADEV *dev, srv_cls_param_t *srv_p) {
-  srv_p->class_type = ATM_ABR;
-  srv_p->pcr        = dev->LineRate;
-  srv_p->mcr        = 0;
-  srv_p->icr        = 0x055cb7;
-  srv_p->tbe        = 0xffffff;
-  srv_p->frtt       = 0x3a;
-  srv_p->rif        = 0xf;
-  srv_p->rdf        = 0xb;
-  srv_p->nrm        = 0x4;
-  srv_p->trm        = 0x7;
-  srv_p->cdf        = 0x3;
-  srv_p->adtf       = 50;
-}
-
-static int
-ia_open_abr_vc(IADEV *dev, srv_cls_param_t *srv_p, 
-                                                struct atm_vcc *vcc, u8 flag)
-{
-  f_vc_abr_entry  *f_abr_vc;
-  r_vc_abr_entry  *r_abr_vc;
-  u32		icr;
-  u8		trm, nrm, crm;
-  u16		adtf, air, *ptr16;	
-  f_abr_vc =(f_vc_abr_entry *)dev->MAIN_VC_TABLE_ADDR;
-  f_abr_vc += vcc->vci;       
-  switch (flag) {
-     case 1: /* FFRED initialization */
-#if 0  /* sanity check */
-       if (srv_p->pcr == 0)
-          return INVALID_PCR;
-       if (srv_p->pcr > dev->LineRate)
-          srv_p->pcr = dev->LineRate;
-       if ((srv_p->mcr + dev->sum_mcr) > dev->LineRate)
-	  return MCR_UNAVAILABLE;
-       if (srv_p->mcr > srv_p->pcr)
-	  return INVALID_MCR;
-       if (!(srv_p->icr))
-	  srv_p->icr = srv_p->pcr;
-       if ((srv_p->icr < srv_p->mcr) || (srv_p->icr > srv_p->pcr))
-	  return INVALID_ICR;
-       if ((srv_p->tbe < MIN_TBE) || (srv_p->tbe > MAX_TBE))
-	  return INVALID_TBE;
-       if ((srv_p->frtt < MIN_FRTT) || (srv_p->frtt > MAX_FRTT))
-	  return INVALID_FRTT;
-       if (srv_p->nrm > MAX_NRM)
-	  return INVALID_NRM;
-       if (srv_p->trm > MAX_TRM)
-	  return INVALID_TRM;
-       if (srv_p->adtf > MAX_ADTF)
-          return INVALID_ADTF;
-       else if (srv_p->adtf == 0)
-	  srv_p->adtf = 1;
-       if (srv_p->cdf > MAX_CDF)
-	  return INVALID_CDF;
-       if (srv_p->rif > MAX_RIF)
-	  return INVALID_RIF;
-       if (srv_p->rdf > MAX_RDF)
-	  return INVALID_RDF;
-#endif
-       memset ((caddr_t)f_abr_vc, 0, sizeof(*f_abr_vc));
-       f_abr_vc->f_vc_type = ABR;
-       nrm = 2 << srv_p->nrm;     /* (2 ** (srv_p->nrm +1)) */
-			          /* i.e 2**n = 2 << (n-1) */
-       f_abr_vc->f_nrm = nrm << 8 | nrm;
-       trm = 100000/(2 << (16 - srv_p->trm));
-       if ( trm == 0) trm = 1;
-       f_abr_vc->f_nrmexp =(((srv_p->nrm +1) & 0x0f) << 12)|(MRM << 8) | trm;
-       crm = srv_p->tbe / nrm;
-       if (crm == 0) crm = 1;
-       f_abr_vc->f_crm = crm & 0xff;
-       f_abr_vc->f_pcr = cellrate_to_float(srv_p->pcr);
-       icr = min( srv_p->icr, (srv_p->tbe > srv_p->frtt) ?
-				((srv_p->tbe/srv_p->frtt)*1000000) :
-				(1000000/(srv_p->frtt/srv_p->tbe)));
-       f_abr_vc->f_icr = cellrate_to_float(icr);
-       adtf = (10000 * srv_p->adtf)/8192;
-       if (adtf == 0) adtf = 1; 
-       f_abr_vc->f_cdf = ((7 - srv_p->cdf) << 12 | adtf) & 0xfff;
-       f_abr_vc->f_mcr = cellrate_to_float(srv_p->mcr);
-       f_abr_vc->f_acr = f_abr_vc->f_icr;
-       f_abr_vc->f_status = 0x0042;
-       break;
-    case 0: /* RFRED initialization */	
-       ptr16 = (u_short *)(dev->reass_ram + REASS_TABLE*dev->memSize); 
-       *(ptr16 + vcc->vci) = NO_AAL5_PKT | REASS_ABR;
-       r_abr_vc = (r_vc_abr_entry*)(dev->reass_ram+ABR_VC_TABLE*dev->memSize);
-       r_abr_vc += vcc->vci;
-       r_abr_vc->r_status_rdf = (15 - srv_p->rdf) & 0x000f;
-       air = srv_p->pcr << (15 - srv_p->rif);
-       if (air == 0) air = 1;
-       r_abr_vc->r_air = cellrate_to_float(air);
-       dev->testTable[vcc->vci]->vc_status = VC_ACTIVE | VC_ABR;
-       dev->sum_mcr	   += srv_p->mcr;
-       dev->n_abr++;
-       break;
-    default:
-       break;
-  }
-  return	0;
-}
-static int ia_cbr_setup (IADEV *dev, struct atm_vcc *vcc) {
-   u32 rateLow=0, rateHigh, rate;
-   int entries;
-   struct ia_vcc *ia_vcc;
-
-   int   idealSlot =0, testSlot, toBeAssigned, inc;
-   u32   spacing;
-   u16  *SchedTbl, *TstSchedTbl;
-   u16  cbrVC, vcIndex;
-   u32   fracSlot    = 0;
-   u32   sp_mod      = 0;
-   u32   sp_mod2     = 0;
-
-   /* IpAdjustTrafficParams */
-   if (vcc->qos.txtp.max_pcr <= 0) {
-      IF_ERR(printk("PCR for CBR not defined\n");)
-      return -1;
-   }
-   rate = vcc->qos.txtp.max_pcr;
-   entries = rate / dev->Granularity;
-   IF_CBR(printk("CBR: CBR entries=0x%x for rate=0x%x & Gran=0x%x\n",
-                                entries, rate, dev->Granularity);)
-   if (entries < 1)
-      IF_CBR(printk("CBR: Bandwidth smaller than granularity of CBR table\n");) 
-   rateLow  =  entries * dev->Granularity;
-   rateHigh = (entries + 1) * dev->Granularity;
-   if (3*(rate - rateLow) > (rateHigh - rate))
-      entries++;
-   if (entries > dev->CbrRemEntries) {
-      IF_CBR(printk("CBR: Not enough bandwidth to support this PCR.\n");)
-      IF_CBR(printk("Entries = 0x%x, CbrRemEntries = 0x%x.\n",
-                                       entries, dev->CbrRemEntries);)
-      return -EBUSY;
-   }   
-
-   ia_vcc = INPH_IA_VCC(vcc);
-   ia_vcc->NumCbrEntry = entries; 
-   dev->sum_mcr += entries * dev->Granularity; 
-   /* IaFFrednInsertCbrSched */
-   // Starting at an arbitrary location, place the entries into the table
-   // as smoothly as possible
-   cbrVC   = 0;
-   spacing = dev->CbrTotEntries / entries;
-   sp_mod  = dev->CbrTotEntries % entries; // get modulo
-   toBeAssigned = entries;
-   fracSlot = 0;
-   vcIndex  = vcc->vci;
-   IF_CBR(printk("Vci=0x%x,Spacing=0x%x,Sp_mod=0x%x\n",vcIndex,spacing,sp_mod);)
-   while (toBeAssigned)
-   {
-      // If this is the first time, start the table loading for this connection
-      // as close to entryPoint as possible.
-      if (toBeAssigned == entries)
-      {
-         idealSlot = dev->CbrEntryPt;
-         dev->CbrEntryPt += 2;    // Adding 2 helps to prevent clumping
-         if (dev->CbrEntryPt >= dev->CbrTotEntries) 
-            dev->CbrEntryPt -= dev->CbrTotEntries;// Wrap if necessary
-      } else {
-         idealSlot += (u32)(spacing + fracSlot); // Point to the next location
-         // in the table that would be  smoothest
-         fracSlot = ((sp_mod + sp_mod2) / entries);  // get new integer part
-         sp_mod2  = ((sp_mod + sp_mod2) % entries);  // calc new fractional part
-      }
-      if (idealSlot >= (int)dev->CbrTotEntries) 
-         idealSlot -= dev->CbrTotEntries;  
-      // Continuously check around this ideal value until a null
-      // location is encountered.
-      SchedTbl = (u16*)(dev->seg_ram+CBR_SCHED_TABLE*dev->memSize); 
-      inc = 0;
-      testSlot = idealSlot;
-      TstSchedTbl = (u16*)(SchedTbl+testSlot);  //set index and read in value
-      IF_CBR(printk("CBR Testslot 0x%x AT Location 0x%p, NumToAssign=%d\n",
-                                testSlot, TstSchedTbl,toBeAssigned);)
-      memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
-      while (cbrVC)  // If another VC at this location, we have to keep looking
-      {
-          inc++;
-          testSlot = idealSlot - inc;
-          if (testSlot < 0) { // Wrap if necessary
-             testSlot += dev->CbrTotEntries;
-             IF_CBR(printk("Testslot Wrap. STable Start=0x%p,Testslot=%d\n",
-                                                       SchedTbl,testSlot);)
-          }
-          TstSchedTbl = (u16 *)(SchedTbl + testSlot);  // set table index
-          memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC)); 
-          if (!cbrVC)
-             break;
-          testSlot = idealSlot + inc;
-          if (testSlot >= (int)dev->CbrTotEntries) { // Wrap if necessary
-             testSlot -= dev->CbrTotEntries;
-             IF_CBR(printk("TotCbrEntries=%d",dev->CbrTotEntries);)
-             IF_CBR(printk(" Testslot=0x%x ToBeAssgned=%d\n", 
-                                            testSlot, toBeAssigned);)
-          } 
-          // set table index and read in value
-          TstSchedTbl = (u16*)(SchedTbl + testSlot);
-          IF_CBR(printk("Reading CBR Tbl from 0x%p, CbrVal=0x%x Iteration %d\n",
-                          TstSchedTbl,cbrVC,inc);)
-          memcpy((caddr_t)&cbrVC,(caddr_t)TstSchedTbl,sizeof(cbrVC));
-       } /* while */
-       // Move this VCI number into this location of the CBR Sched table.
-       memcpy((caddr_t)TstSchedTbl, (caddr_t)&vcIndex, sizeof(*TstSchedTbl));
-       dev->CbrRemEntries--;
-       toBeAssigned--;
-   } /* while */ 
-
-   /* IaFFrednCbrEnable */
-   dev->NumEnabledCBR++;
-   if (dev->NumEnabledCBR == 1) {
-       writew((CBR_EN | UBR_EN | ABR_EN | (0x23 << 2)), dev->seg_reg+STPARMS);
-       IF_CBR(printk("CBR is enabled\n");)
-   }
-   return 0;
-}
-static void ia_cbrVc_close (struct atm_vcc *vcc) {
-   IADEV *iadev;
-   u16 *SchedTbl, NullVci = 0;
-   u32 i, NumFound;
-
-   iadev = INPH_IA_DEV(vcc->dev);
-   iadev->NumEnabledCBR--;
-   SchedTbl = (u16*)(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize);
-   if (iadev->NumEnabledCBR == 0) {
-      writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);
-      IF_CBR (printk("CBR support disabled\n");)
-   }
-   NumFound = 0;
-   for (i=0; i < iadev->CbrTotEntries; i++)
-   {
-      if (*SchedTbl == vcc->vci) {
-         iadev->CbrRemEntries++;
-         *SchedTbl = NullVci;
-         IF_CBR(NumFound++;)
-      }
-      SchedTbl++;   
-   } 
-   IF_CBR(printk("Exit ia_cbrVc_close, NumRemoved=%d\n",NumFound);)
-}
-
-static int ia_avail_descs(IADEV *iadev) {
-   int tmp = 0;
-   ia_hack_tcq(iadev);
-   if (iadev->host_tcq_wr >= iadev->ffL.tcq_rd)
-      tmp = (iadev->host_tcq_wr - iadev->ffL.tcq_rd) / 2;
-   else
-      tmp = (iadev->ffL.tcq_ed - iadev->ffL.tcq_rd + 2 + iadev->host_tcq_wr -
-                   iadev->ffL.tcq_st) / 2;
-   return tmp;
-}    
-
-static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb);
-
-static int ia_que_tx (IADEV *iadev) { 
-   struct sk_buff *skb;
-   int num_desc;
-   struct atm_vcc *vcc;
-   num_desc = ia_avail_descs(iadev);
-
-   while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
-      if (!(vcc = ATM_SKB(skb)->vcc)) {
-         dev_kfree_skb_any(skb);
-         printk("ia_que_tx: Null vcc\n");
-         break;
-      }
-      if (!test_bit(ATM_VF_READY,&vcc->flags)) {
-         dev_kfree_skb_any(skb);
-         printk("Free the SKB on closed vci %d \n", vcc->vci);
-         break;
-      }
-      if (ia_pkt_tx (vcc, skb)) {
-         skb_queue_head(&iadev->tx_backlog, skb);
-      }
-      num_desc--;
-   }
-   return 0;
-}
-
-static void ia_tx_poll (IADEV *iadev) {
-   struct atm_vcc *vcc = NULL;
-   struct sk_buff *skb = NULL, *skb1 = NULL;
-   struct ia_vcc *iavcc;
-   IARTN_Q *  rtne;
-
-   ia_hack_tcq(iadev);
-   while ( (rtne = ia_deque_rtn_q(&iadev->tx_return_q))) {
-       skb = rtne->data.txskb;
-       if (!skb) {
-           printk("ia_tx_poll: skb is null\n");
-           goto out;
-       }
-       vcc = ATM_SKB(skb)->vcc;
-       if (!vcc) {
-           printk("ia_tx_poll: vcc is null\n");
-           dev_kfree_skb_any(skb);
-	   goto out;
-       }
-
-       iavcc = INPH_IA_VCC(vcc);
-       if (!iavcc) {
-           printk("ia_tx_poll: iavcc is null\n");
-           dev_kfree_skb_any(skb);
-	   goto out;
-       }
-
-       skb1 = skb_dequeue(&iavcc->txing_skb);
-       while (skb1 && (skb1 != skb)) {
-          if (!(IA_SKB_STATE(skb1) & IA_TX_DONE)) {
-             printk("IA_tx_intr: Vci %d lost pkt!!!\n", vcc->vci);
-          }
-          IF_ERR(printk("Release the SKB not match\n");)
-          if ((vcc->pop) && (skb1->len != 0))
-          {
-             vcc->pop(vcc, skb1);
-             IF_EVENT(printk("Transmit Done - skb 0x%lx return\n",
-                                                          (long)skb1);)
-          }
-          else 
-             dev_kfree_skb_any(skb1);
-          skb1 = skb_dequeue(&iavcc->txing_skb);
-       }                                                        
-       if (!skb1) {
-          IF_EVENT(printk("IA: Vci %d - skb not found requeued\n",vcc->vci);)
-          ia_enque_head_rtn_q (&iadev->tx_return_q, rtne);
-          break;
-       }
-       if ((vcc->pop) && (skb->len != 0))
-       {
-          vcc->pop(vcc, skb);
-          IF_EVENT(printk("Tx Done - skb 0x%lx return\n",(long)skb);)
-       }
-       else 
-          dev_kfree_skb_any(skb);
-       kfree(rtne);
-    }
-    ia_que_tx(iadev);
-out:
-    return;
-}
-#if 0
-static void ia_eeprom_put (IADEV *iadev, u32 addr, u_short val)
-{
-        u32	t;
-	int	i;
-	/*
-	 * Issue a command to enable writes to the NOVRAM
-	 */
-	NVRAM_CMD (EXTEND + EWEN);
-	NVRAM_CLR_CE;
-	/*
-	 * issue the write command
-	 */
-	NVRAM_CMD(IAWRITE + addr);
-	/* 
-	 * Send the data, starting with D15, then D14, and so on for 16 bits
-	 */
-	for (i=15; i>=0; i--) {
-		NVRAM_CLKOUT (val & 0x8000);
-		val <<= 1;
-	}
-	NVRAM_CLR_CE;
-	CFG_OR(NVCE);
-	t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
-	while (!(t & NVDO))
-		t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); 
-
-	NVRAM_CLR_CE;
-	/*
-	 * disable writes again
-	 */
-	NVRAM_CMD(EXTEND + EWDS)
-	NVRAM_CLR_CE;
-	CFG_AND(~NVDI);
-}
-#endif
-
-static u16 ia_eeprom_get (IADEV *iadev, u32 addr)
-{
-	u_short	val;
-        u32	t;
-	int	i;
-	/*
-	 * Read the first bit that was clocked with the falling edge of
-	 * the last command data clock
-	 */
-	NVRAM_CMD(IAREAD + addr);
-	/*
-	 * Now read the rest of the bits, the next bit read is D14, then D13,
-	 * and so on.
-	 */
-	val = 0;
-	for (i=15; i>=0; i--) {
-		NVRAM_CLKIN(t);
-		val |= (t << i);
-	}
-	NVRAM_CLR_CE;
-	CFG_AND(~NVDI);
-	return val;
-}
-
-static void ia_hw_type(IADEV *iadev) {
-   u_short memType = ia_eeprom_get(iadev, 25);   
-   iadev->memType = memType;
-   if ((memType & MEM_SIZE_MASK) == MEM_SIZE_1M) {
-      iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ; 
-   } else if ((memType & MEM_SIZE_MASK) == MEM_SIZE_512K) {
-      if (IA_TX_BUF == DFL_TX_BUFFERS)
-        iadev->num_tx_desc = IA_TX_BUF / 2;
-      else 
-        iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      if (IA_RX_BUF == DFL_RX_BUFFERS)
-        iadev->num_rx_desc = IA_RX_BUF / 2;
-      else
-        iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ;
-   }
-   else {
-      if (IA_TX_BUF == DFL_TX_BUFFERS) 
-        iadev->num_tx_desc = IA_TX_BUF / 8;
-      else
-        iadev->num_tx_desc = IA_TX_BUF;
-      iadev->tx_buf_sz = IA_TX_BUF_SZ;
-      if (IA_RX_BUF == DFL_RX_BUFFERS)
-        iadev->num_rx_desc = IA_RX_BUF / 8;
-      else
-        iadev->num_rx_desc = IA_RX_BUF;
-      iadev->rx_buf_sz = IA_RX_BUF_SZ; 
-   } 
-   iadev->rx_pkt_ram = TX_PACKET_RAM + (iadev->num_tx_desc * iadev->tx_buf_sz); 
-   IF_INIT(printk("BUF: tx=%d,sz=%d rx=%d sz= %d rx_pkt_ram=%d\n",
-         iadev->num_tx_desc, iadev->tx_buf_sz, iadev->num_rx_desc,
-         iadev->rx_buf_sz, iadev->rx_pkt_ram);)
-
-#if 0
-   if ((memType & FE_MASK) == FE_SINGLE_MODE) {
-      iadev->phy_type = PHY_OC3C_S;
-   else if ((memType & FE_MASK) == FE_UTP_OPTION)
-      iadev->phy_type = PHY_UTP155;
-   else
-     iadev->phy_type = PHY_OC3C_M;
-#endif
-   
-   iadev->phy_type = memType & FE_MASK;
-   IF_INIT(printk("memType = 0x%x iadev->phy_type = 0x%x\n", 
-                                         memType,iadev->phy_type);)
-   if (iadev->phy_type == FE_25MBIT_PHY) 
-      iadev->LineRate = (u32)(((25600000/8)*26)/(27*53));
-   else if (iadev->phy_type == FE_DS3_PHY)
-      iadev->LineRate = (u32)(((44736000/8)*26)/(27*53));
-   else if (iadev->phy_type == FE_E3_PHY) 
-      iadev->LineRate = (u32)(((34368000/8)*26)/(27*53));
-   else
-       iadev->LineRate = (u32)(ATM_OC3_PCR);
-   IF_INIT(printk("iadev->LineRate = %d \n", iadev->LineRate);)
-
-}
-
-static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg)
-{
-	return readl(ia->phy + (reg >> 2));
-}
-
-static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val)
-{
-	writel(val, ia->phy + (reg >> 2));
-}
-
-static void ia_frontend_intr(struct iadev_priv *iadev)
-{
-	u32 status;
-
-	if (iadev->phy_type & FE_25MBIT_PHY) {
-		status = ia_phy_read32(iadev, MB25_INTR_STATUS);
-		iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0;
-	} else if (iadev->phy_type & FE_DS3_PHY) {
-		ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT);
-		status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
-		iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
-	} else if (iadev->phy_type & FE_E3_PHY) {
-		ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND);
-		status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
-		iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
-	} else {
-		status = ia_phy_read32(iadev, SUNI_RSOP_STATUS);
-		iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1;
-	}
-
-	printk(KERN_INFO "IA: SUNI carrier %s\n",
-		iadev->carrier_detect ? "detected" : "lost signal");
-}
-
-static void ia_mb25_init(struct iadev_priv *iadev)
-{
-#if 0
-   mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
-#endif
-	ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC);
-	ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0);
-
-	iadev->carrier_detect =
-		(ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0;
-}
-
-struct ia_reg {
-	u16 reg;
-	u16 val;
-};
-
-static void ia_phy_write(struct iadev_priv *iadev,
-			 const struct ia_reg *regs, int len)
-{
-	while (len--) {
-		ia_phy_write32(iadev, regs->reg, regs->val);
-		regs++;
-	}
-}
-
-static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_ds3_init[] = {
-		{ SUNI_DS3_FRM_INTR_ENBL,	0x17 },
-		{ SUNI_DS3_FRM_CFG,		0x01 },
-		{ SUNI_DS3_TRAN_CFG,		0x01 },
-		{ SUNI_CONFIG,			0 },
-		{ SUNI_SPLR_CFG,		0 },
-		{ SUNI_SPLT_CFG,		0 }
-	};
-	u32 status;
-
-	status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
-	iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
-
-	ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init));
-}
-
-static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_e3_init[] = {
-		{ SUNI_E3_FRM_FRAM_OPTIONS,		0x04 },
-		{ SUNI_E3_FRM_MAINT_OPTIONS,		0x20 },
-		{ SUNI_E3_FRM_FRAM_INTR_ENBL,		0x1d },
-		{ SUNI_E3_FRM_MAINT_INTR_ENBL,		0x30 },
-		{ SUNI_E3_TRAN_STAT_DIAG_OPTIONS,	0 },
-		{ SUNI_E3_TRAN_FRAM_OPTIONS,		0x01 },
-		{ SUNI_CONFIG,				SUNI_PM7345_E3ENBL },
-		{ SUNI_SPLR_CFG,			0x41 },
-		{ SUNI_SPLT_CFG,			0x41 }
-	};
-	u32 status;
-
-	status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
-	iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
-	ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init));
-}
-
-static void ia_suni_pm7345_init(struct iadev_priv *iadev)
-{
-	static const struct ia_reg suni_init[] = {
-		/* Enable RSOP loss of signal interrupt. */
-		{ SUNI_INTR_ENBL,		0x28 },
-		/* Clear error counters. */
-		{ SUNI_ID_RESET,		0 },
-		/* Clear "PMCTST" in master test register. */
-		{ SUNI_MASTER_TEST,		0 },
-
-		{ SUNI_RXCP_CTRL,		0x2c },
-		{ SUNI_RXCP_FCTRL,		0x81 },
-
-		{ SUNI_RXCP_IDLE_PAT_H1,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H2,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H3,	0 },
-		{ SUNI_RXCP_IDLE_PAT_H4,	0x01 },
-
-		{ SUNI_RXCP_IDLE_MASK_H1,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H2,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H3,	0xff },
-		{ SUNI_RXCP_IDLE_MASK_H4,	0xfe },
-
-		{ SUNI_RXCP_CELL_PAT_H1,	0 },
-		{ SUNI_RXCP_CELL_PAT_H2,	0 },
-		{ SUNI_RXCP_CELL_PAT_H3,	0 },
-		{ SUNI_RXCP_CELL_PAT_H4,	0x01 },
-
-		{ SUNI_RXCP_CELL_MASK_H1,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H2,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H3,	0xff },
-		{ SUNI_RXCP_CELL_MASK_H4,	0xff },
-
-		{ SUNI_TXCP_CTRL,		0xa4 },
-		{ SUNI_TXCP_INTR_EN_STS,	0x10 },
-		{ SUNI_TXCP_IDLE_PAT_H5,	0x55 }
-	};
-
-	if (iadev->phy_type & FE_DS3_PHY)
-		ia_suni_pm7345_init_ds3(iadev);
-	else
-		ia_suni_pm7345_init_e3(iadev);
-
-	ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init));
-
-	ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, SUNI_CONFIG) &
-		~(SUNI_PM7345_LLB | SUNI_PM7345_CLB |
-		  SUNI_PM7345_DLB | SUNI_PM7345_PLB));
-#ifdef __SNMP__
-   suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
-#endif /* __SNMP__ */
-   return;
-}
-
-
-/***************************** IA_LIB END *****************************/
-    
-#ifdef CONFIG_ATM_IA_DEBUG
-static int tcnter = 0;
-static void xdump( u_char*  cp, int  length, char*  prefix )
-{
-    int col, count;
-    u_char prntBuf[120];
-    u_char*  pBuf = prntBuf;
-    count = 0;
-    while(count < length){
-        pBuf += sprintf( pBuf, "%s", prefix );
-        for(col = 0;count + col < length && col < 16; col++){
-            if (col != 0 && (col % 4) == 0)
-                pBuf += sprintf( pBuf, " " );
-            pBuf += sprintf( pBuf, "%02X ", cp[count + col] );
-        }
-        while(col++ < 16){      /* pad end of buffer with blanks */
-            if ((col % 4) == 0)
-                sprintf( pBuf, " " );
-            pBuf += sprintf( pBuf, "   " );
-        }
-        pBuf += sprintf( pBuf, "  " );
-        for(col = 0;count + col < length && col < 16; col++){
-		u_char c = cp[count + col];
-
-		if (isascii(c) && isprint(c))
-			pBuf += sprintf(pBuf, "%c", c);
-		else
-			pBuf += sprintf(pBuf, ".");
-                }
-        printk("%s\n", prntBuf);
-        count += col;
-        pBuf = prntBuf;
-    }
-
-}  /* close xdump(... */
-#endif /* CONFIG_ATM_IA_DEBUG */
-
-  
-static struct atm_dev *ia_boards = NULL;  
-  
-#define ACTUAL_RAM_BASE \
-	RAM_BASE*((iadev->mem)/(128 * 1024))  
-#define ACTUAL_SEG_RAM_BASE \
-	IPHASE5575_FRAG_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
-#define ACTUAL_REASS_RAM_BASE \
-	IPHASE5575_REASS_CONTROL_RAM_BASE*((iadev->mem)/(128 * 1024))  
-  
-  
-/*-- some utilities and memory allocation stuff will come here -------------*/  
-  
-static void desc_dbg(IADEV *iadev) {
-
-  u_short tcq_wr_ptr, tcq_st_ptr, tcq_ed_ptr;
-  u32 i;
-  void __iomem *tmp;
-  // regval = readl((u32)ia_cmds->maddr);
-  tcq_wr_ptr =  readw(iadev->seg_reg+TCQ_WR_PTR);
-  printk("B_tcq_wr = 0x%x desc = %d last desc = %d\n",
-                     tcq_wr_ptr, readw(iadev->seg_ram+tcq_wr_ptr),
-                     readw(iadev->seg_ram+tcq_wr_ptr-2));
-  printk(" host_tcq_wr = 0x%x  host_tcq_rd = 0x%x \n",  iadev->host_tcq_wr, 
-                   iadev->ffL.tcq_rd);
-  tcq_st_ptr =  readw(iadev->seg_reg+TCQ_ST_ADR);
-  tcq_ed_ptr =  readw(iadev->seg_reg+TCQ_ED_ADR);
-  printk("tcq_st_ptr = 0x%x    tcq_ed_ptr = 0x%x \n", tcq_st_ptr, tcq_ed_ptr);
-  i = 0;
-  while (tcq_st_ptr != tcq_ed_ptr) {
-      tmp = iadev->seg_ram+tcq_st_ptr;
-      printk("TCQ slot %d desc = %d  Addr = %p\n", i++, readw(tmp), tmp);
-      tcq_st_ptr += 2;
-  }
-  for(i=0; i <iadev->num_tx_desc; i++)
-      printk("Desc_tbl[%d] = %d \n", i, iadev->desc_tbl[i].timestamp);
-} 
-  
-  
-/*----------------------------- Receiving side stuff --------------------------*/  
- 
-static void rx_excp_rcvd(struct atm_dev *dev)  
-{  
-#if 0 /* closing the receiving size will cause too many excp int */  
-  IADEV *iadev;  
-  u_short state;  
-  u_short excpq_rd_ptr;  
-  //u_short *ptr;  
-  int vci, error = 1;  
-  iadev = INPH_IA_DEV(dev);  
-  state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-  while((state & EXCPQ_EMPTY) != EXCPQ_EMPTY)  
-  { printk("state = %x \n", state); 
-        excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_RD_PTR) & 0xffff;  
- printk("state = %x excpq_rd_ptr = %x \n", state, excpq_rd_ptr); 
-        if (excpq_rd_ptr == *(u16*)(iadev->reass_reg + EXCP_Q_WR_PTR))
-            IF_ERR(printk("excpq_rd_ptr is wrong!!!\n");)
-        // TODO: update exception stat
-	vci = readw(iadev->reass_ram+excpq_rd_ptr);  
-	error = readw(iadev->reass_ram+excpq_rd_ptr+2) & 0x0007;  
-        // pwang_test
-	excpq_rd_ptr += 4;  
-	if (excpq_rd_ptr > (readw(iadev->reass_reg + EXCP_Q_ED_ADR)& 0xffff))  
- 	    excpq_rd_ptr = readw(iadev->reass_reg + EXCP_Q_ST_ADR)& 0xffff;
-	writew( excpq_rd_ptr, iadev->reass_reg + EXCP_Q_RD_PTR);  
-        state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-  }  
-#endif
-}  
-  
-static void free_desc(struct atm_dev *dev, int desc)  
-{  
-	IADEV *iadev;  
-	iadev = INPH_IA_DEV(dev);  
-        writew(desc, iadev->reass_ram+iadev->rfL.fdq_wr); 
-	iadev->rfL.fdq_wr +=2;
-	if (iadev->rfL.fdq_wr > iadev->rfL.fdq_ed)
-		iadev->rfL.fdq_wr =  iadev->rfL.fdq_st;  
-	writew(iadev->rfL.fdq_wr, iadev->reass_reg+FREEQ_WR_PTR);  
-}  
-  
-  
-static int rx_pkt(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct atm_vcc *vcc;  
-	unsigned short status;  
-	struct rx_buf_desc __iomem *buf_desc_ptr;  
-	int desc;   
-	struct dle* wr_ptr;  
-	int len;  
-	struct sk_buff *skb;  
-	u_int buf_addr, dma_addr;  
-
-	iadev = INPH_IA_DEV(dev);  
-	if (iadev->rfL.pcq_rd == (readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff)) 
-	{  
-   	    printk(KERN_ERR DEV_LABEL "(itf %d) Receive queue empty\n", dev->number);  
-	    return -EINVAL;  
-	}  
-	/* mask 1st 3 bits to get the actual descno. */  
-	desc = readw(iadev->reass_ram+iadev->rfL.pcq_rd) & 0x1fff;  
-        IF_RX(printk("reass_ram = %p iadev->rfL.pcq_rd = 0x%x desc = %d\n", 
-                                    iadev->reass_ram, iadev->rfL.pcq_rd, desc);
-              printk(" pcq_wr_ptr = 0x%x\n",
-                               readw(iadev->reass_reg+PCQ_WR_PTR)&0xffff);)
-	/* update the read pointer  - maybe we shud do this in the end*/  
-	if ( iadev->rfL.pcq_rd== iadev->rfL.pcq_ed) 
-		iadev->rfL.pcq_rd = iadev->rfL.pcq_st;  
-	else  
-		iadev->rfL.pcq_rd += 2;
-	writew(iadev->rfL.pcq_rd, iadev->reass_reg+PCQ_RD_PTR);  
-  
-	/* get the buffer desc entry.  
-		update stuff. - doesn't seem to be any update necessary  
-	*/  
-	buf_desc_ptr = iadev->RX_DESC_BASE_ADDR;
-	/* make the ptr point to the corresponding buffer desc entry */  
-	buf_desc_ptr += desc;	  
-        if (!desc || (desc > iadev->num_rx_desc) || 
-                      ((buf_desc_ptr->vc_index & 0xffff) >= iadev->num_vc)) {
-            free_desc(dev, desc);
-            IF_ERR(printk("IA: bad descriptor desc = %d \n", desc);)
-            return -1;
-        }
-	vcc = iadev->rx_open[buf_desc_ptr->vc_index & 0xffff];  
-	if (!vcc)  
-	{      
-                free_desc(dev, desc); 
-		printk("IA: null vcc, drop PDU\n");  
-		return -1;  
-	}  
-	  
-  
-	/* might want to check the status bits for errors */  
-	status = (u_short) (buf_desc_ptr->desc_mode);  
-	if (status & (RX_CER | RX_PTE | RX_OFL))  
-	{  
-                atomic_inc(&vcc->stats->rx_err);
-		IF_ERR(printk("IA: bad packet, dropping it");)  
-                if (status & RX_CER) { 
-                    IF_ERR(printk(" cause: packet CRC error\n");)
-                }
-                else if (status & RX_PTE) {
-                    IF_ERR(printk(" cause: packet time out\n");)
-                }
-                else {
-                    IF_ERR(printk(" cause: buffer overflow\n");)
-                }
-		goto out_free_desc;
-	}  
-  
-	/*  
-		build DLE.	  
-	*/  
-  
-	buf_addr = (buf_desc_ptr->buf_start_hi << 16) | buf_desc_ptr->buf_start_lo;  
-	dma_addr = (buf_desc_ptr->dma_start_hi << 16) | buf_desc_ptr->dma_start_lo;  
-	len = dma_addr - buf_addr;  
-        if (len > iadev->rx_buf_sz) {
-           printk("Over %d bytes sdu received, dropped!!!\n", iadev->rx_buf_sz);
-           atomic_inc(&vcc->stats->rx_err);
-	   goto out_free_desc;
-        }
-		  
-        if (!(skb = atm_alloc_charge(vcc, len, GFP_ATOMIC))) {
-           if (vcc->vci < 32)
-              printk("Drop control packets\n");
-	   goto out_free_desc;
-        }
-	skb_put(skb,len);  
-        // pwang_test
-        ATM_SKB(skb)->vcc = vcc;
-        ATM_DESC(skb) = desc;        
-	skb_queue_tail(&iadev->rx_dma_q, skb);  
-
-	/* Build the DLE structure */  
-	wr_ptr = iadev->rx_dle_q.write;  
-	wr_ptr->sys_pkt_addr = dma_map_single(&iadev->pci->dev, skb->data,
-					      len, DMA_FROM_DEVICE);
-	wr_ptr->local_pkt_addr = buf_addr;  
-	wr_ptr->bytes = len;	/* We don't know this do we ?? */  
-	wr_ptr->mode = DMA_INT_ENABLE;  
-  
-	/* shud take care of wrap around here too. */  
-        if(++wr_ptr == iadev->rx_dle_q.end)
-             wr_ptr = iadev->rx_dle_q.start;
-	iadev->rx_dle_q.write = wr_ptr;  
-	udelay(1);  
-	/* Increment transaction counter */  
-	writel(1, iadev->dma+IPHASE5575_RX_COUNTER);   
-out:	return 0;  
-out_free_desc:
-        free_desc(dev, desc);
-        goto out;
-}  
-  
-static void rx_intr(struct atm_dev *dev)  
-{  
-  IADEV *iadev;  
-  u_short status;  
-  u_short state, i;  
-  
-  iadev = INPH_IA_DEV(dev);  
-  status = readl(iadev->reass_reg+REASS_INTR_STATUS_REG) & 0xffff;  
-  IF_EVENT(printk("rx_intr: status = 0x%x\n", status);)
-  if (status & RX_PKT_RCVD)  
-  {  
-	/* do something */  
-	/* Basically recvd an interrupt for receiving a packet.  
-	A descriptor would have been written to the packet complete   
-	queue. Get all the descriptors and set up dma to move the   
-	packets till the packet complete queue is empty..  
-	*/  
-	state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-        IF_EVENT(printk("Rx intr status: RX_PKT_RCVD %08x\n", status);) 
-	while(!(state & PCQ_EMPTY))  
-	{  
-             rx_pkt(dev);  
-	     state = readl(iadev->reass_reg + STATE_REG) & 0xffff;  
-	}  
-        iadev->rxing = 1;
-  }  
-  if (status & RX_FREEQ_EMPT)  
-  {   
-     if (iadev->rxing) {
-        iadev->rx_tmp_cnt = iadev->rx_pkt_cnt;
-        iadev->rx_tmp_jif = jiffies; 
-        iadev->rxing = 0;
-     } 
-     else if ((time_after(jiffies, iadev->rx_tmp_jif + 50)) &&
-               ((iadev->rx_pkt_cnt - iadev->rx_tmp_cnt) == 0)) {
-        for (i = 1; i <= iadev->num_rx_desc; i++)
-               free_desc(dev, i);
-printk("Test logic RUN!!!!\n");
-        writew( ~(RX_FREEQ_EMPT|RX_EXCP_RCVD),iadev->reass_reg+REASS_MASK_REG);
-        iadev->rxing = 1;
-     }
-     IF_EVENT(printk("Rx intr status: RX_FREEQ_EMPT %08x\n", status);)  
-  }  
-
-  if (status & RX_EXCP_RCVD)  
-  {  
-	/* probably need to handle the exception queue also. */  
-	IF_EVENT(printk("Rx intr status: RX_EXCP_RCVD %08x\n", status);)  
-	rx_excp_rcvd(dev);  
-  }  
-
-
-  if (status & RX_RAW_RCVD)  
-  {  
-	/* need to handle the raw incoming cells. This deepnds on   
-	whether we have programmed to receive the raw cells or not.  
-	Else ignore. */  
-	IF_EVENT(printk("Rx intr status:  RX_RAW_RCVD %08x\n", status);)  
-  }  
-}  
-  
-  
-static void rx_dle_intr(struct atm_dev *dev)  
-{  
-  IADEV *iadev;  
-  struct atm_vcc *vcc;   
-  struct sk_buff *skb;  
-  int desc;  
-  u_short state;   
-  struct dle *dle, *cur_dle;  
-  u_int dle_lp;  
-  int len;
-  iadev = INPH_IA_DEV(dev);  
- 
-  /* free all the dles done, that is just update our own dle read pointer   
-	- do we really need to do this. Think not. */  
-  /* DMA is done, just get all the recevie buffers from the rx dma queue  
-	and push them up to the higher layer protocol. Also free the desc  
-	associated with the buffer. */  
-  dle = iadev->rx_dle_q.read;  
-  dle_lp = readl(iadev->dma+IPHASE5575_RX_LIST_ADDR) & (sizeof(struct dle)*DLE_ENTRIES - 1);  
-  cur_dle = (struct dle*)(iadev->rx_dle_q.start + (dle_lp >> 4));  
-  while(dle != cur_dle)  
-  {  
-      /* free the DMAed skb */  
-      skb = skb_dequeue(&iadev->rx_dma_q);  
-      if (!skb)  
-         goto INCR_DLE;
-      desc = ATM_DESC(skb);
-      free_desc(dev, desc);  
-               
-      if (!(len = skb->len))
-      {  
-          printk("rx_dle_intr: skb len 0\n");  
-	  dev_kfree_skb_any(skb);  
-      }  
-      else  
-      {  
-          struct cpcs_trailer *trailer;
-          u_short length;
-          struct ia_vcc *ia_vcc;
-
-	  dma_unmap_single(&iadev->pci->dev, iadev->rx_dle_q.write->sys_pkt_addr,
-			   len, DMA_FROM_DEVICE);
-          /* no VCC related housekeeping done as yet. lets see */  
-          vcc = ATM_SKB(skb)->vcc;
-	  if (!vcc) {
-	      printk("IA: null vcc\n");  
-              dev_kfree_skb_any(skb);
-              goto INCR_DLE;
-          }
-          ia_vcc = INPH_IA_VCC(vcc);
-          if (ia_vcc == NULL)
-          {
-             atomic_inc(&vcc->stats->rx_err);
-             atm_return(vcc, skb->truesize);
-             dev_kfree_skb_any(skb);
-             goto INCR_DLE;
-           }
-          // get real pkt length  pwang_test
-          trailer = (struct cpcs_trailer*)((u_char *)skb->data +
-                                 skb->len - sizeof(*trailer));
-	  length = swap_byte_order(trailer->length);
-          if ((length > iadev->rx_buf_sz) || (length > 
-                              (skb->len - sizeof(struct cpcs_trailer))))
-          {
-             atomic_inc(&vcc->stats->rx_err);
-             IF_ERR(printk("rx_dle_intr: Bad  AAL5 trailer %d (skb len %d)", 
-                                                            length, skb->len);)
-             atm_return(vcc, skb->truesize);
-             dev_kfree_skb_any(skb);
-             goto INCR_DLE;
-          }
-          skb_trim(skb, length);
-          
-	  /* Display the packet */  
-	  IF_RXPKT(printk("\nDmad Recvd data: len = %d \n", skb->len);  
-          xdump(skb->data, skb->len, "RX: ");
-          printk("\n");)
-
-	  IF_RX(printk("rx_dle_intr: skb push");)  
-	  vcc->push(vcc,skb);  
-	  atomic_inc(&vcc->stats->rx);
-          iadev->rx_pkt_cnt++;
-      }  
-INCR_DLE:
-      if (++dle == iadev->rx_dle_q.end)  
-    	  dle = iadev->rx_dle_q.start;  
-  }  
-  iadev->rx_dle_q.read = dle;  
-  
-  /* if the interrupts are masked because there were no free desc available,  
-		unmask them now. */ 
-  if (!iadev->rxing) {
-     state = readl(iadev->reass_reg + STATE_REG) & 0xffff;
-     if (!(state & FREEQ_EMPTY)) {
-        state = readl(iadev->reass_reg + REASS_MASK_REG) & 0xffff;
-        writel(state & ~(RX_FREEQ_EMPT |/* RX_EXCP_RCVD |*/ RX_PKT_RCVD),
-                                      iadev->reass_reg+REASS_MASK_REG);
-        iadev->rxing++; 
-     }
-  }
-}  
-  
-  
-static int open_rx(struct atm_vcc *vcc)  
-{  
-	IADEV *iadev;  
-	u_short __iomem *vc_table;  
-	u_short __iomem *reass_ptr;  
-	IF_EVENT(printk("iadev: open_rx %d.%d\n", vcc->vpi, vcc->vci);)
-
-	if (vcc->qos.rxtp.traffic_class == ATM_NONE) return 0;    
-	iadev = INPH_IA_DEV(vcc->dev);  
-        if (vcc->qos.rxtp.traffic_class == ATM_ABR) {  
-           if (iadev->phy_type & FE_25MBIT_PHY) {
-               printk("IA:  ABR not support\n");
-               return -EINVAL; 
-           }
-        }
-	/* Make only this VCI in the vc table valid and let all   
-		others be invalid entries */  
-	vc_table = iadev->reass_ram+RX_VC_TABLE*iadev->memSize;
-	vc_table += vcc->vci;
-	/* mask the last 6 bits and OR it with 3 for 1K VCs */  
-
-        *vc_table = vcc->vci << 6;
-	/* Also keep a list of open rx vcs so that we can attach them with  
-		incoming PDUs later. */  
-	if ((vcc->qos.rxtp.traffic_class == ATM_ABR) || 
-                                (vcc->qos.txtp.traffic_class == ATM_ABR))  
-	{  
-                srv_cls_param_t srv_p;
-                init_abr_vc(iadev, &srv_p);
-                ia_open_abr_vc(iadev, &srv_p, vcc, 0);
-	} 
-       	else {  /* for UBR  later may need to add CBR logic */
-        	reass_ptr = iadev->reass_ram+REASS_TABLE*iadev->memSize;
-           	reass_ptr += vcc->vci;
-           	*reass_ptr = NO_AAL5_PKT;
-       	}
-	
-	if (iadev->rx_open[vcc->vci])  
-		printk(KERN_CRIT DEV_LABEL "(itf %d): VCI %d already open\n",  
-			vcc->dev->number, vcc->vci);  
-	iadev->rx_open[vcc->vci] = vcc;  
-	return 0;  
-}  
-  
-static int rx_init(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct rx_buf_desc __iomem *buf_desc_ptr;  
-	unsigned long rx_pkt_start = 0;  
-	void *dle_addr;  
-	struct abr_vc_table  *abr_vc_table; 
-	u16 *vc_table;  
-	u16 *reass_table;  
-	int i,j, vcsize_sel;  
-	u_short freeq_st_adr;  
-	u_short *freeq_start;  
-  
-	iadev = INPH_IA_DEV(dev);  
-  //    spin_lock_init(&iadev->rx_lock); 
-  
-	/* Allocate 4k bytes - more aligned than needed (4k boundary) */
-	dle_addr = dma_alloc_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE,
-				      &iadev->rx_dle_dma, GFP_KERNEL);
-	if (!dle_addr)  {  
-		printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");
-		goto err_out;
-	}
-	iadev->rx_dle_q.start = (struct dle *)dle_addr;
-	iadev->rx_dle_q.read = iadev->rx_dle_q.start;  
-	iadev->rx_dle_q.write = iadev->rx_dle_q.start;  
-	iadev->rx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
-	/* the end of the dle q points to the entry after the last  
-	DLE that can be used. */  
-  
-	/* write the upper 20 bits of the start address to rx list address register */  
-	/* We know this is 32bit bus addressed so the following is safe */
-	writel(iadev->rx_dle_dma & 0xfffff000,
-	       iadev->dma + IPHASE5575_RX_LIST_ADDR);  
-	IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n",
-                      iadev->dma+IPHASE5575_TX_LIST_ADDR,
-                      readl(iadev->dma + IPHASE5575_TX_LIST_ADDR));
-	printk("Rx Dle list addr: 0x%p value: 0x%0x\n",
-                      iadev->dma+IPHASE5575_RX_LIST_ADDR,
-                      readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));)
-  
-	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
-	writew(0, iadev->reass_reg+MODE_REG);  
-	writew(RESET_REASS, iadev->reass_reg+REASS_COMMAND_REG);  
-  
-	/* Receive side control memory map  
-	   -------------------------------  
-  
-		Buffer descr	0x0000 (736 - 23K)  
-		VP Table	0x5c00 (256 - 512)  
-		Except q	0x5e00 (128 - 512)  
-		Free buffer q	0x6000 (1K - 2K)  
-		Packet comp q	0x6800 (1K - 2K)  
-		Reass Table	0x7000 (1K - 2K)  
-		VC Table	0x7800 (1K - 2K)  
-		ABR VC Table	0x8000 (1K - 32K)  
-	*/  
-	  
-	/* Base address for Buffer Descriptor Table */  
-	writew(RX_DESC_BASE >> 16, iadev->reass_reg+REASS_DESC_BASE);  
-	/* Set the buffer size register */  
-	writew(iadev->rx_buf_sz, iadev->reass_reg+BUF_SIZE);  
-  
-	/* Initialize each entry in the Buffer Descriptor Table */  
-        iadev->RX_DESC_BASE_ADDR = iadev->reass_ram+RX_DESC_BASE*iadev->memSize;
-	buf_desc_ptr = iadev->RX_DESC_BASE_ADDR;
-	memset_io(buf_desc_ptr, 0, sizeof(*buf_desc_ptr));
-	buf_desc_ptr++;  
-	rx_pkt_start = iadev->rx_pkt_ram;  
-	for(i=1; i<=iadev->num_rx_desc; i++)  
-	{  
-		memset_io(buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-		buf_desc_ptr->buf_start_hi = rx_pkt_start >> 16;  
-		buf_desc_ptr->buf_start_lo = rx_pkt_start & 0x0000ffff;  
-		buf_desc_ptr++;		  
-		rx_pkt_start += iadev->rx_buf_sz;  
-	}  
-	IF_INIT(printk("Rx Buffer desc ptr: 0x%p\n", buf_desc_ptr);)
-        i = FREE_BUF_DESC_Q*iadev->memSize; 
-	writew(i >> 16,  iadev->reass_reg+REASS_QUEUE_BASE); 
-        writew(i, iadev->reass_reg+FREEQ_ST_ADR);
-        writew(i+iadev->num_rx_desc*sizeof(u_short), 
-                                         iadev->reass_reg+FREEQ_ED_ADR);
-        writew(i, iadev->reass_reg+FREEQ_RD_PTR);
-        writew(i+iadev->num_rx_desc*sizeof(u_short), 
-                                        iadev->reass_reg+FREEQ_WR_PTR);    
-	/* Fill the FREEQ with all the free descriptors. */  
-	freeq_st_adr = readw(iadev->reass_reg+FREEQ_ST_ADR);  
-	freeq_start = (u_short *)(iadev->reass_ram+freeq_st_adr);  
-	for(i=1; i<=iadev->num_rx_desc; i++)  
-	{  
-		*freeq_start = (u_short)i;  
-		freeq_start++;  
-	}  
-	IF_INIT(printk("freeq_start: 0x%p\n", freeq_start);)
-        /* Packet Complete Queue */
-        i = (PKT_COMP_Q * iadev->memSize) & 0xffff;
-        writew(i, iadev->reass_reg+PCQ_ST_ADR);
-        writew(i+iadev->num_vc*sizeof(u_short), iadev->reass_reg+PCQ_ED_ADR);
-        writew(i, iadev->reass_reg+PCQ_RD_PTR);
-        writew(i, iadev->reass_reg+PCQ_WR_PTR);
-
-        /* Exception Queue */
-        i = (EXCEPTION_Q * iadev->memSize) & 0xffff;
-        writew(i, iadev->reass_reg+EXCP_Q_ST_ADR);
-        writew(i + NUM_RX_EXCP * sizeof(RX_ERROR_Q), 
-                                             iadev->reass_reg+EXCP_Q_ED_ADR);
-        writew(i, iadev->reass_reg+EXCP_Q_RD_PTR);
-        writew(i, iadev->reass_reg+EXCP_Q_WR_PTR); 
- 
-    	/* Load local copy of FREEQ and PCQ ptrs */
-        iadev->rfL.fdq_st = readw(iadev->reass_reg+FREEQ_ST_ADR) & 0xffff;
-       	iadev->rfL.fdq_ed = readw(iadev->reass_reg+FREEQ_ED_ADR) & 0xffff ;
-	iadev->rfL.fdq_rd = readw(iadev->reass_reg+FREEQ_RD_PTR) & 0xffff;
-	iadev->rfL.fdq_wr = readw(iadev->reass_reg+FREEQ_WR_PTR) & 0xffff;
-        iadev->rfL.pcq_st = readw(iadev->reass_reg+PCQ_ST_ADR) & 0xffff;
-	iadev->rfL.pcq_ed = readw(iadev->reass_reg+PCQ_ED_ADR) & 0xffff;
-	iadev->rfL.pcq_rd = readw(iadev->reass_reg+PCQ_RD_PTR) & 0xffff;
-	iadev->rfL.pcq_wr = readw(iadev->reass_reg+PCQ_WR_PTR) & 0xffff;
-	
-        IF_INIT(printk("INIT:pcq_st:0x%x pcq_ed:0x%x pcq_rd:0x%x pcq_wr:0x%x", 
-              iadev->rfL.pcq_st, iadev->rfL.pcq_ed, iadev->rfL.pcq_rd, 
-              iadev->rfL.pcq_wr);)		  
-	/* just for check - no VP TBL */  
-	/* VP Table */  
-	/* writew(0x0b80, iadev->reass_reg+VP_LKUP_BASE); */  
-	/* initialize VP Table for invalid VPIs  
-		- I guess we can write all 1s or 0x000f in the entire memory  
-		  space or something similar.  
-	*/  
-  
-	/* This seems to work and looks right to me too !!! */  
-        i =  REASS_TABLE * iadev->memSize;
-	writew((i >> 3), iadev->reass_reg+REASS_TABLE_BASE);   
- 	/* initialize Reassembly table to I don't know what ???? */  
-	reass_table = (u16 *)(iadev->reass_ram+i);  
-        j = REASS_TABLE_SZ * iadev->memSize;
-	for(i=0; i < j; i++)  
-		*reass_table++ = NO_AAL5_PKT;  
-       i = 8*1024;
-       vcsize_sel =  0;
-       while (i != iadev->num_vc) {
-          i /= 2;
-          vcsize_sel++;
-       }
-       i = RX_VC_TABLE * iadev->memSize;
-       writew(((i>>3) & 0xfff8) | vcsize_sel, iadev->reass_reg+VC_LKUP_BASE);
-       vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);  
-        j = RX_VC_TABLE_SZ * iadev->memSize;
-	for(i = 0; i < j; i++)  
-	{  
-		/* shift the reassembly pointer by 3 + lower 3 bits of   
-		vc_lkup_base register (=3 for 1K VCs) and the last byte   
-		is those low 3 bits.   
-		Shall program this later.  
-		*/  
-		*vc_table = (i << 6) | 15;	/* for invalid VCI */  
-		vc_table++;  
-	}  
-        /* ABR VC table */
-        i =  ABR_VC_TABLE * iadev->memSize;
-        writew(i >> 3, iadev->reass_reg+ABR_LKUP_BASE);
-                   
-        i = ABR_VC_TABLE * iadev->memSize;
-	abr_vc_table = (struct abr_vc_table *)(iadev->reass_ram+i);  
-        j = REASS_TABLE_SZ * iadev->memSize;
-        memset ((char*)abr_vc_table, 0, j * sizeof(*abr_vc_table));
-    	for(i = 0; i < j; i++) {   		
-		abr_vc_table->rdf = 0x0003;
-             	abr_vc_table->air = 0x5eb1;
-	       	abr_vc_table++;   	
-        }  
-
-	/* Initialize other registers */  
-  
-	/* VP Filter Register set for VC Reassembly only */  
-	writew(0xff00, iadev->reass_reg+VP_FILTER);  
-        writew(0, iadev->reass_reg+XTRA_RM_OFFSET);
-	writew(0x1,  iadev->reass_reg+PROTOCOL_ID);
-
-	/* Packet Timeout Count  related Registers : 
-	   Set packet timeout to occur in about 3 seconds
-	   Set Packet Aging Interval count register to overflow in about 4 us
- 	*/  
-        writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT );
-
-        i = (j >> 6) & 0xFF;
-        j += 2 * (j - 1);
-        i |= ((j << 2) & 0xFF00);
-        writew(i, iadev->reass_reg+TMOUT_RANGE);
-
-        /* initiate the desc_tble */
-        for(i=0; i<iadev->num_tx_desc;i++)
-            iadev->desc_tbl[i].timestamp = 0;
-
-	/* to clear the interrupt status register - read it */  
-	readw(iadev->reass_reg+REASS_INTR_STATUS_REG);   
-  
-	/* Mask Register - clear it */  
-	writew(~(RX_FREEQ_EMPT|RX_PKT_RCVD), iadev->reass_reg+REASS_MASK_REG);  
-  
-	skb_queue_head_init(&iadev->rx_dma_q);  
-	iadev->rx_free_desc_qhead = NULL;   
-
-	iadev->rx_open = kcalloc(iadev->num_vc, sizeof(void *), GFP_KERNEL);
-	if (!iadev->rx_open) {
-		printk(KERN_ERR DEV_LABEL "itf %d couldn't get free page\n",
-		dev->number);  
-		goto err_free_dle;
-	}  
-
-        iadev->rxing = 1;
-        iadev->rx_pkt_cnt = 0;
-	/* Mode Register */  
-	writew(R_ONLINE, iadev->reass_reg+MODE_REG);  
-	return 0;  
-
-err_free_dle:
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->rx_dle_q.start,
-			  iadev->rx_dle_dma);
-err_out:
-	return -ENOMEM;
-}  
-  
-
-/*  
-	The memory map suggested in appendix A and the coding for it.   
-	Keeping it around just in case we change our mind later.  
-  
-		Buffer descr	0x0000 (128 - 4K)  
-		UBR sched	0x1000 (1K - 4K)  
-		UBR Wait q	0x2000 (1K - 4K)  
-		Commn queues	0x3000 Packet Ready, Trasmit comp(0x3100)  
-					(128 - 256) each  
-		extended VC	0x4000 (1K - 8K)  
-		ABR sched	0x6000	and ABR wait queue (1K - 2K) each  
-		CBR sched	0x7000 (as needed)  
-		VC table	0x8000 (1K - 32K)  
-*/  
-  
-static void tx_intr(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	unsigned short status;  
-        unsigned long flags;
-
-	iadev = INPH_IA_DEV(dev);  
-  
-	status = readl(iadev->seg_reg+SEG_INTR_STATUS_REG);  
-        if (status & TRANSMIT_DONE){
-
-           IF_EVENT(printk("Transmit Done Intr logic run\n");)
-           spin_lock_irqsave(&iadev->tx_lock, flags);
-           ia_tx_poll(iadev);
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-           writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
-           if (iadev->close_pending)  
-               wake_up(&iadev->close_wait);
-        }     	  
-	if (status & TCQ_NOT_EMPTY)  
-	{  
-	    IF_EVENT(printk("TCQ_NOT_EMPTY int received\n");)  
-	}  
-}  
-  
-static void tx_dle_intr(struct atm_dev *dev)
-{
-        IADEV *iadev;
-        struct dle *dle, *cur_dle; 
-        struct sk_buff *skb;
-        struct atm_vcc *vcc;
-        struct ia_vcc  *iavcc;
-        u_int dle_lp;
-        unsigned long flags;
-
-        iadev = INPH_IA_DEV(dev);
-        spin_lock_irqsave(&iadev->tx_lock, flags);   
-        dle = iadev->tx_dle_q.read;
-        dle_lp = readl(iadev->dma+IPHASE5575_TX_LIST_ADDR) & 
-                                        (sizeof(struct dle)*DLE_ENTRIES - 1);
-        cur_dle = (struct dle*)(iadev->tx_dle_q.start + (dle_lp >> 4));
-        while (dle != cur_dle)
-        {
-            /* free the DMAed skb */ 
-            skb = skb_dequeue(&iadev->tx_dma_q); 
-            if (!skb) break;
-
-	    /* Revenge of the 2 dle (skb + trailer) used in ia_pkt_tx() */
-	    if (!((dle - iadev->tx_dle_q.start)%(2*sizeof(struct dle)))) {
-		dma_unmap_single(&iadev->pci->dev, dle->sys_pkt_addr, skb->len,
-				 DMA_TO_DEVICE);
-	    }
-            vcc = ATM_SKB(skb)->vcc;
-            if (!vcc) {
-                  printk("tx_dle_intr: vcc is null\n");
-		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
-                  dev_kfree_skb_any(skb);
-
-                  return;
-            }
-            iavcc = INPH_IA_VCC(vcc);
-            if (!iavcc) {
-                  printk("tx_dle_intr: iavcc is null\n");
-		  spin_unlock_irqrestore(&iadev->tx_lock, flags);
-                  dev_kfree_skb_any(skb);
-                  return;
-            }
-            if (vcc->qos.txtp.pcr >= iadev->rate_limit) {
-               if ((vcc->pop) && (skb->len != 0))
-               {     
-                 vcc->pop(vcc, skb);
-               } 
-               else {
-                 dev_kfree_skb_any(skb);
-               }
-            }
-            else { /* Hold the rate-limited skb for flow control */
-               IA_SKB_STATE(skb) |= IA_DLED;
-               skb_queue_tail(&iavcc->txing_skb, skb);
-            }
-            IF_EVENT(printk("tx_dle_intr: enque skb = 0x%p \n", skb);)
-            if (++dle == iadev->tx_dle_q.end)
-                 dle = iadev->tx_dle_q.start;
-        }
-        iadev->tx_dle_q.read = dle;
-        spin_unlock_irqrestore(&iadev->tx_lock, flags);
-}
-  
-static int open_tx(struct atm_vcc *vcc)  
-{  
-	struct ia_vcc *ia_vcc;  
-	IADEV *iadev;  
-	struct main_vc *vc;  
-	struct ext_vc *evc;  
-        int ret;
-	IF_EVENT(printk("iadev: open_tx entered vcc->vci = %d\n", vcc->vci);)  
-	if (vcc->qos.txtp.traffic_class == ATM_NONE) return 0;  
-	iadev = INPH_IA_DEV(vcc->dev);  
-        
-        if (iadev->phy_type & FE_25MBIT_PHY) {
-           if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-               printk("IA:  ABR not support\n");
-               return -EINVAL; 
-           }
-	  if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-               printk("IA:  CBR not support\n");
-               return -EINVAL; 
-          }
-        }
-        ia_vcc =  INPH_IA_VCC(vcc);
-        memset((caddr_t)ia_vcc, 0, sizeof(*ia_vcc));
-        if (vcc->qos.txtp.max_sdu > 
-                         (iadev->tx_buf_sz - sizeof(struct cpcs_trailer))){
-           printk("IA:  SDU size over (%d) the configured SDU size %d\n",
-		  vcc->qos.txtp.max_sdu,iadev->tx_buf_sz);
-	   vcc->dev_data = NULL;
-           kfree(ia_vcc);
-           return -EINVAL; 
-        }
-	ia_vcc->vc_desc_cnt = 0;
-        ia_vcc->txing = 1;
-
-        /* find pcr */
-        if (vcc->qos.txtp.max_pcr == ATM_MAX_PCR) 
-           vcc->qos.txtp.pcr = iadev->LineRate;
-        else if ((vcc->qos.txtp.max_pcr == 0)&&( vcc->qos.txtp.pcr <= 0))
-           vcc->qos.txtp.pcr = iadev->LineRate;
-        else if ((vcc->qos.txtp.max_pcr > vcc->qos.txtp.pcr) && (vcc->qos.txtp.max_pcr> 0)) 
-           vcc->qos.txtp.pcr = vcc->qos.txtp.max_pcr;
-        if (vcc->qos.txtp.pcr > iadev->LineRate)
-             vcc->qos.txtp.pcr = iadev->LineRate;
-        ia_vcc->pcr = vcc->qos.txtp.pcr;
-
-        if (ia_vcc->pcr > (iadev->LineRate / 6) ) ia_vcc->ltimeout = HZ / 10;
-        else if (ia_vcc->pcr > (iadev->LineRate / 130)) ia_vcc->ltimeout = HZ;
-        else if (ia_vcc->pcr <= 170) ia_vcc->ltimeout = 16 * HZ;
-        else ia_vcc->ltimeout = 2700 * HZ  / ia_vcc->pcr;
-        if (ia_vcc->pcr < iadev->rate_limit)
-           skb_queue_head_init (&ia_vcc->txing_skb);
-        if (ia_vcc->pcr < iadev->rate_limit) {
-	   struct sock *sk = sk_atm(vcc);
-
-	   if (vcc->qos.txtp.max_sdu != 0) {
-               if (ia_vcc->pcr > 60000)
-                  sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 5;
-               else if (ia_vcc->pcr > 2000)
-                  sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 4;
-               else
-                 sk->sk_sndbuf = vcc->qos.txtp.max_sdu * 3;
-           }
-           else
-             sk->sk_sndbuf = 24576;
-        }
-           
-	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
-	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
-	vc += vcc->vci;  
-	evc += vcc->vci;  
-	memset((caddr_t)vc, 0, sizeof(*vc));  
-	memset((caddr_t)evc, 0, sizeof(*evc));  
-	  
-	/* store the most significant 4 bits of vci as the last 4 bits   
-		of first part of atm header.  
-	   store the last 12 bits of vci as first 12 bits of the second  
-		part of the atm header.  
-	*/  
-	evc->atm_hdr1 = (vcc->vci >> 12) & 0x000f;  
-	evc->atm_hdr2 = (vcc->vci & 0x0fff) << 4;  
- 
-	/* check the following for different traffic classes */  
-	if (vcc->qos.txtp.traffic_class == ATM_UBR)  
-	{  
-		vc->type = UBR;  
-                vc->status = CRC_APPEND;
-		vc->acr = cellrate_to_float(iadev->LineRate);  
-                if (vcc->qos.txtp.pcr > 0) 
-                   vc->acr = cellrate_to_float(vcc->qos.txtp.pcr);  
-                IF_UBR(printk("UBR: txtp.pcr = 0x%x f_rate = 0x%x\n", 
-                                             vcc->qos.txtp.max_pcr,vc->acr);)
-	}  
-	else if (vcc->qos.txtp.traffic_class == ATM_ABR)  
-	{       srv_cls_param_t srv_p;
-		IF_ABR(printk("Tx ABR VCC\n");)  
-                init_abr_vc(iadev, &srv_p);
-                if (vcc->qos.txtp.pcr > 0) 
-                   srv_p.pcr = vcc->qos.txtp.pcr;
-                if (vcc->qos.txtp.min_pcr > 0) {
-                   int tmpsum = iadev->sum_mcr+iadev->sum_cbr+vcc->qos.txtp.min_pcr;
-                   if (tmpsum > iadev->LineRate)
-                       return -EBUSY;
-                   srv_p.mcr = vcc->qos.txtp.min_pcr;
-                   iadev->sum_mcr += vcc->qos.txtp.min_pcr;
-                } 
-                else srv_p.mcr = 0;
-                if (vcc->qos.txtp.icr)
-                   srv_p.icr = vcc->qos.txtp.icr;
-                if (vcc->qos.txtp.tbe)
-                   srv_p.tbe = vcc->qos.txtp.tbe;
-                if (vcc->qos.txtp.frtt)
-                   srv_p.frtt = vcc->qos.txtp.frtt;
-                if (vcc->qos.txtp.rif)
-                   srv_p.rif = vcc->qos.txtp.rif;
-                if (vcc->qos.txtp.rdf)
-                   srv_p.rdf = vcc->qos.txtp.rdf;
-                if (vcc->qos.txtp.nrm_pres)
-                   srv_p.nrm = vcc->qos.txtp.nrm;
-                if (vcc->qos.txtp.trm_pres)
-                   srv_p.trm = vcc->qos.txtp.trm;
-                if (vcc->qos.txtp.adtf_pres)
-                   srv_p.adtf = vcc->qos.txtp.adtf;
-                if (vcc->qos.txtp.cdf_pres)
-                   srv_p.cdf = vcc->qos.txtp.cdf;    
-                if (srv_p.icr > srv_p.pcr)
-                   srv_p.icr = srv_p.pcr;    
-                IF_ABR(printk("ABR:vcc->qos.txtp.max_pcr = %d  mcr = %d\n", 
-                                                      srv_p.pcr, srv_p.mcr);)
-		ia_open_abr_vc(iadev, &srv_p, vcc, 1);
-	} else if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-                if (iadev->phy_type & FE_25MBIT_PHY) {
-                    printk("IA:  CBR not support\n");
-                    return -EINVAL; 
-                }
-                if (vcc->qos.txtp.max_pcr > iadev->LineRate) {
-                   IF_CBR(printk("PCR is not available\n");)
-                   return -1;
-                }
-                vc->type = CBR;
-                vc->status = CRC_APPEND;
-                if ((ret = ia_cbr_setup (iadev, vcc)) < 0) {     
-                    return ret;
-                }
-	} else {
-		printk("iadev:  Non UBR, ABR and CBR traffic not supported\n");
-	}
-        
-        iadev->testTable[vcc->vci]->vc_status |= VC_ACTIVE;
-	IF_EVENT(printk("ia open_tx returning \n");)  
-	return 0;  
-}  
-  
-  
-static int tx_init(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	struct tx_buf_desc *buf_desc_ptr;
-	unsigned int tx_pkt_start;  
-	void *dle_addr;  
-	int i;  
-	u_short tcq_st_adr;  
-	u_short *tcq_start;  
-	u_short prq_st_adr;  
-	u_short *prq_start;  
-	struct main_vc *vc;  
-	struct ext_vc *evc;   
-        u_short tmp16;
-        u32 vcsize_sel;
- 
-	iadev = INPH_IA_DEV(dev);  
-        spin_lock_init(&iadev->tx_lock);
- 
-	IF_INIT(printk("Tx MASK REG: 0x%0x\n", 
-                                readw(iadev->seg_reg+SEG_MASK_REG));)  
-
-	/* Allocate 4k (boundary aligned) bytes */
-	dle_addr = dma_alloc_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE,
-				      &iadev->tx_dle_dma, GFP_KERNEL);
-	if (!dle_addr)  {
-		printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n");
-		goto err_out;
-	}
-	iadev->tx_dle_q.start = (struct dle*)dle_addr;  
-	iadev->tx_dle_q.read = iadev->tx_dle_q.start;  
-	iadev->tx_dle_q.write = iadev->tx_dle_q.start;  
-	iadev->tx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES);
-
-	/* write the upper 20 bits of the start address to tx list address register */  
-	writel(iadev->tx_dle_dma & 0xfffff000,
-	       iadev->dma + IPHASE5575_TX_LIST_ADDR);  
-	writew(0xffff, iadev->seg_reg+SEG_MASK_REG);  
-	writew(0, iadev->seg_reg+MODE_REG_0);  
-	writew(RESET_SEG, iadev->seg_reg+SEG_COMMAND_REG);  
-        iadev->MAIN_VC_TABLE_ADDR = iadev->seg_ram+MAIN_VC_TABLE*iadev->memSize;
-        iadev->EXT_VC_TABLE_ADDR = iadev->seg_ram+EXT_VC_TABLE*iadev->memSize;
-        iadev->ABR_SCHED_TABLE_ADDR=iadev->seg_ram+ABR_SCHED_TABLE*iadev->memSize;
-  
-	/*  
-	   Transmit side control memory map  
-	   --------------------------------    
-	 Buffer descr 	0x0000 (128 - 4K)  
-	 Commn queues	0x1000	Transmit comp, Packet ready(0x1400)   
-					(512 - 1K) each  
-					TCQ - 4K, PRQ - 5K  
-	 CBR Table 	0x1800 (as needed) - 6K  
-	 UBR Table	0x3000 (1K - 4K) - 12K  
-	 UBR Wait queue	0x4000 (1K - 4K) - 16K  
-	 ABR sched	0x5000	and ABR wait queue (1K - 2K) each  
-				ABR Tbl - 20K, ABR Wq - 22K   
-	 extended VC	0x6000 (1K - 8K) - 24K  
-	 VC Table	0x8000 (1K - 32K) - 32K  
-	  
-	Between 0x2000 (8K) and 0x3000 (12K) there is 4K space left for VBR Tbl  
-	and Wait q, which can be allotted later.  
-	*/  
-     
-	/* Buffer Descriptor Table Base address */  
-	writew(TX_DESC_BASE, iadev->seg_reg+SEG_DESC_BASE);  
-  
-	/* initialize each entry in the buffer descriptor table */  
-	buf_desc_ptr =(struct tx_buf_desc *)(iadev->seg_ram+TX_DESC_BASE);  
-	memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-	buf_desc_ptr++;  
-	tx_pkt_start = TX_PACKET_RAM;  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		memset((caddr_t)buf_desc_ptr, 0, sizeof(*buf_desc_ptr));  
-		buf_desc_ptr->desc_mode = AAL5;  
-		buf_desc_ptr->buf_start_hi = tx_pkt_start >> 16;  
-		buf_desc_ptr->buf_start_lo = tx_pkt_start & 0x0000ffff;  
-		buf_desc_ptr++;		  
-		tx_pkt_start += iadev->tx_buf_sz;  
-	}  
-	iadev->tx_buf = kmalloc_objs(*iadev->tx_buf, iadev->num_tx_desc);
-        if (!iadev->tx_buf) {
-            printk(KERN_ERR DEV_LABEL " couldn't get mem\n");
-	    goto err_free_dle;
-        }
-       	for (i= 0; i< iadev->num_tx_desc; i++)
-       	{
-	    struct cpcs_trailer *cpcs;
- 
-       	    cpcs = kmalloc_obj(*cpcs, GFP_KERNEL | GFP_DMA);
-            if(!cpcs) {                
-		printk(KERN_ERR DEV_LABEL " couldn't get freepage\n"); 
-		goto err_free_tx_bufs;
-            }
-	    iadev->tx_buf[i].cpcs = cpcs;
-	    iadev->tx_buf[i].dma_addr = dma_map_single(&iadev->pci->dev,
-						       cpcs,
-						       sizeof(*cpcs),
-						       DMA_TO_DEVICE);
-        }
-	iadev->desc_tbl = kmalloc_objs(*iadev->desc_tbl, iadev->num_tx_desc);
-	if (!iadev->desc_tbl) {
-		printk(KERN_ERR DEV_LABEL " couldn't get mem\n");
-		goto err_free_all_tx_bufs;
-	}
-  
-	/* Communication Queues base address */  
-        i = TX_COMP_Q * iadev->memSize;
-	writew(i >> 16, iadev->seg_reg+SEG_QUEUE_BASE);  
-  
-	/* Transmit Complete Queue */  
-	writew(i, iadev->seg_reg+TCQ_ST_ADR);  
-	writew(i, iadev->seg_reg+TCQ_RD_PTR);  
-	writew(i+iadev->num_tx_desc*sizeof(u_short),iadev->seg_reg+TCQ_WR_PTR); 
-	iadev->host_tcq_wr = i + iadev->num_tx_desc*sizeof(u_short);
-        writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
-                                              iadev->seg_reg+TCQ_ED_ADR); 
-	/* Fill the TCQ with all the free descriptors. */  
-	tcq_st_adr = readw(iadev->seg_reg+TCQ_ST_ADR);  
-	tcq_start = (u_short *)(iadev->seg_ram+tcq_st_adr);  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		*tcq_start = (u_short)i;  
-		tcq_start++;  
-	}  
-  
-	/* Packet Ready Queue */  
-        i = PKT_RDY_Q * iadev->memSize; 
-	writew(i, iadev->seg_reg+PRQ_ST_ADR);  
-	writew(i+2 * iadev->num_tx_desc * sizeof(u_short), 
-                                              iadev->seg_reg+PRQ_ED_ADR);
-	writew(i, iadev->seg_reg+PRQ_RD_PTR);  
-	writew(i, iadev->seg_reg+PRQ_WR_PTR);  
-	 
-        /* Load local copy of PRQ and TCQ ptrs */
-        iadev->ffL.prq_st = readw(iadev->seg_reg+PRQ_ST_ADR) & 0xffff;
-	iadev->ffL.prq_ed = readw(iadev->seg_reg+PRQ_ED_ADR) & 0xffff;
- 	iadev->ffL.prq_wr = readw(iadev->seg_reg+PRQ_WR_PTR) & 0xffff;
-
-	iadev->ffL.tcq_st = readw(iadev->seg_reg+TCQ_ST_ADR) & 0xffff;
-	iadev->ffL.tcq_ed = readw(iadev->seg_reg+TCQ_ED_ADR) & 0xffff;
-	iadev->ffL.tcq_rd = readw(iadev->seg_reg+TCQ_RD_PTR) & 0xffff;
-
-	/* Just for safety initializing the queue to have desc 1 always */  
-	/* Fill the PRQ with all the free descriptors. */  
-	prq_st_adr = readw(iadev->seg_reg+PRQ_ST_ADR);  
-	prq_start = (u_short *)(iadev->seg_ram+prq_st_adr);  
-	for(i=1; i<=iadev->num_tx_desc; i++)  
-	{  
-		*prq_start = (u_short)0;	/* desc 1 in all entries */  
-		prq_start++;  
-	}  
-	/* CBR Table */  
-        IF_INIT(printk("Start CBR Init\n");)
-#if 1  /* for 1K VC board, CBR_PTR_BASE is 0 */
-        writew(0,iadev->seg_reg+CBR_PTR_BASE);
-#else /* Charlie's logic is wrong ? */
-        tmp16 = (iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize)>>17;
-        IF_INIT(printk("cbr_ptr_base = 0x%x ", tmp16);)
-        writew(tmp16,iadev->seg_reg+CBR_PTR_BASE);
-#endif
-
-        IF_INIT(printk("value in register = 0x%x\n",
-                                   readw(iadev->seg_reg+CBR_PTR_BASE));)
-        tmp16 = (CBR_SCHED_TABLE*iadev->memSize) >> 1;
-        writew(tmp16, iadev->seg_reg+CBR_TAB_BEG);
-        IF_INIT(printk("cbr_tab_beg = 0x%x in reg = 0x%x \n", tmp16,
-                                        readw(iadev->seg_reg+CBR_TAB_BEG));)
-        writew(tmp16, iadev->seg_reg+CBR_TAB_END+1); // CBR_PTR;
-        tmp16 = (CBR_SCHED_TABLE*iadev->memSize + iadev->num_vc*6 - 2) >> 1;
-        writew(tmp16, iadev->seg_reg+CBR_TAB_END);
-        IF_INIT(printk("iadev->seg_reg = 0x%p CBR_PTR_BASE = 0x%x\n",
-               iadev->seg_reg, readw(iadev->seg_reg+CBR_PTR_BASE));)
-        IF_INIT(printk("CBR_TAB_BEG = 0x%x, CBR_TAB_END = 0x%x, CBR_PTR = 0x%x\n",
-          readw(iadev->seg_reg+CBR_TAB_BEG), readw(iadev->seg_reg+CBR_TAB_END),
-          readw(iadev->seg_reg+CBR_TAB_END+1));)
-
-        /* Initialize the CBR Schedualing Table */
-        memset_io(iadev->seg_ram+CBR_SCHED_TABLE*iadev->memSize, 
-                                                          0, iadev->num_vc*6); 
-        iadev->CbrRemEntries = iadev->CbrTotEntries = iadev->num_vc*3;
-        iadev->CbrEntryPt = 0;
-        iadev->Granularity = MAX_ATM_155 / iadev->CbrTotEntries;
-        iadev->NumEnabledCBR = 0;
-
-	/* UBR scheduling Table and wait queue */  
-	/* initialize all bytes of UBR scheduler table and wait queue to 0   
-		- SCHEDSZ is 1K (# of entries).  
-		- UBR Table size is 4K  
-		- UBR wait queue is 4K  
-	   since the table and wait queues are contiguous, all the bytes   
-	   can be initialized by one memeset.
-	*/  
-        
-        vcsize_sel = 0;
-        i = 8*1024;
-        while (i != iadev->num_vc) {
-          i /= 2;
-          vcsize_sel++;
-        }
- 
-        i = MAIN_VC_TABLE * iadev->memSize;
-        writew(vcsize_sel | ((i >> 8) & 0xfff8),iadev->seg_reg+VCT_BASE);
-        i =  EXT_VC_TABLE * iadev->memSize;
-        writew((i >> 8) & 0xfffe, iadev->seg_reg+VCTE_BASE);
-        i = UBR_SCHED_TABLE * iadev->memSize;
-        writew((i & 0xffff) >> 11,  iadev->seg_reg+UBR_SBPTR_BASE);
-        i = UBR_WAIT_Q * iadev->memSize; 
-        writew((i >> 7) & 0xffff,  iadev->seg_reg+UBRWQ_BASE);
- 	memset((caddr_t)(iadev->seg_ram+UBR_SCHED_TABLE*iadev->memSize),
-                                                       0, iadev->num_vc*8);
-	/* ABR scheduling Table(0x5000-0x57ff) and wait queue(0x5800-0x5fff)*/  
-	/* initialize all bytes of ABR scheduler table and wait queue to 0   
-		- SCHEDSZ is 1K (# of entries).  
-		- ABR Table size is 2K  
-		- ABR wait queue is 2K  
-	   since the table and wait queues are contiguous, all the bytes   
-	   can be initialized by one memeset.
-	*/  
-        i = ABR_SCHED_TABLE * iadev->memSize;
-        writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE);
-        i = ABR_WAIT_Q * iadev->memSize;
-        writew((i >> 7) & 0xffff, iadev->seg_reg+ABRWQ_BASE);
- 
-        i = ABR_SCHED_TABLE*iadev->memSize;
-	memset((caddr_t)(iadev->seg_ram+i),  0, iadev->num_vc*4);
-	vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR;  
-	evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR;  
-	iadev->testTable = kmalloc_objs(*iadev->testTable, iadev->num_vc);
-        if (!iadev->testTable) {
-           printk("Get freepage  failed\n");
-	   goto err_free_desc_tbl;
-        }
-	for(i=0; i<iadev->num_vc; i++)  
-	{  
-		memset((caddr_t)vc, 0, sizeof(*vc));  
-		memset((caddr_t)evc, 0, sizeof(*evc));  
-                iadev->testTable[i] = kmalloc_obj(struct testTable_t);
-		if (!iadev->testTable[i])
-			goto err_free_test_tables;
-              	iadev->testTable[i]->lastTime = 0;
- 		iadev->testTable[i]->fract = 0;
-                iadev->testTable[i]->vc_status = VC_UBR;
-		vc++;  
-		evc++;  
-	}  
-  
-	/* Other Initialization */  
-	  
-	/* Max Rate Register */  
-        if (iadev->phy_type & FE_25MBIT_PHY) {
-	   writew(RATE25, iadev->seg_reg+MAXRATE);  
-	   writew((UBR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
-        }
-        else {
-	   writew(cellrate_to_float(iadev->LineRate),iadev->seg_reg+MAXRATE);
-	   writew((UBR_EN | ABR_EN | (0x23 << 2)), iadev->seg_reg+STPARMS);  
-        }
-	/* Set Idle Header Reigisters to be sure */  
-	writew(0, iadev->seg_reg+IDLEHEADHI);  
-	writew(0, iadev->seg_reg+IDLEHEADLO);  
-  
-	/* Program ABR UBR Priority Register  as  PRI_ABR_UBR_EQUAL */
-        writew(0xaa00, iadev->seg_reg+ABRUBR_ARB); 
-
-        iadev->close_pending = 0;
-        init_waitqueue_head(&iadev->close_wait);
-        init_waitqueue_head(&iadev->timeout_wait);
-	skb_queue_head_init(&iadev->tx_dma_q);  
-	ia_init_rtn_q(&iadev->tx_return_q);  
-
-	/* RM Cell Protocol ID and Message Type */  
-	writew(RM_TYPE_4_0, iadev->seg_reg+RM_TYPE);  
-        skb_queue_head_init (&iadev->tx_backlog);
-  
-	/* Mode Register 1 */  
-	writew(MODE_REG_1_VAL, iadev->seg_reg+MODE_REG_1);  
-  
-	/* Mode Register 0 */  
-	writew(T_ONLINE, iadev->seg_reg+MODE_REG_0);  
-  
-	/* Interrupt Status Register - read to clear */  
-	readw(iadev->seg_reg+SEG_INTR_STATUS_REG);  
-  
-	/* Interrupt Mask Reg- don't mask TCQ_NOT_EMPTY interrupt generation */  
-        writew(~(TRANSMIT_DONE | TCQ_NOT_EMPTY), iadev->seg_reg+SEG_MASK_REG);
-        writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);  
-        iadev->tx_pkt_cnt = 0;
-        iadev->rate_limit = iadev->LineRate / 3;
-  
-	return 0;
-
-err_free_test_tables:
-	while (--i >= 0)
-		kfree(iadev->testTable[i]);
-	kfree(iadev->testTable);
-err_free_desc_tbl:
-	kfree(iadev->desc_tbl);
-err_free_all_tx_bufs:
-	i = iadev->num_tx_desc;
-err_free_tx_bufs:
-	while (--i >= 0) {
-		struct cpcs_trailer_desc *desc = iadev->tx_buf + i;
-
-		dma_unmap_single(&iadev->pci->dev, desc->dma_addr,
-				 sizeof(*desc->cpcs), DMA_TO_DEVICE);
-		kfree(desc->cpcs);
-	}
-	kfree(iadev->tx_buf);
-err_free_dle:
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->tx_dle_q.start,
-			  iadev->tx_dle_dma);
-err_out:
-	return -ENOMEM;
-}   
-   
-static irqreturn_t ia_int(int irq, void *dev_id)  
-{  
-   struct atm_dev *dev;  
-   IADEV *iadev;  
-   unsigned int status;  
-   int handled = 0;
-
-   dev = dev_id;  
-   iadev = INPH_IA_DEV(dev);  
-   while( (status = readl(iadev->reg+IPHASE5575_BUS_STATUS_REG) & 0x7f))  
-   { 
-	handled = 1;
-        IF_EVENT(printk("ia_int: status = 0x%x\n", status);) 
-	if (status & STAT_REASSINT)  
-	{  
-	   /* do something */  
-	   IF_EVENT(printk("REASSINT Bus status reg: %08x\n", status);) 
-	   rx_intr(dev);  
-	}  
-	if (status & STAT_DLERINT)  
-	{  
-	   /* Clear this bit by writing a 1 to it. */  
-	   writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
-	   rx_dle_intr(dev);  
-	}  
-	if (status & STAT_SEGINT)  
-	{  
-	   /* do something */ 
-           IF_EVENT(printk("IA: tx_intr \n");) 
-	   tx_intr(dev);  
-	}  
-	if (status & STAT_DLETINT)  
-	{  
-	   writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
-	   tx_dle_intr(dev);  
-	}  
-	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
-	{  
-           if (status & STAT_FEINT) 
-               ia_frontend_intr(iadev);
-	}  
-   }
-   return IRQ_RETVAL(handled);
-}  
-	  
-	  
-	  
-/*----------------------------- entries --------------------------------*/  
-static int get_esi(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	int i;  
-	u32 mac1;  
-	u16 mac2;  
-	  
-	iadev = INPH_IA_DEV(dev);  
-	mac1 = cpu_to_be32(le32_to_cpu(readl(  
-				iadev->reg+IPHASE5575_MAC1)));  
-	mac2 = cpu_to_be16(le16_to_cpu(readl(iadev->reg+IPHASE5575_MAC2)));  
-	IF_INIT(printk("ESI: 0x%08x%04x\n", mac1, mac2);)  
-	for (i=0; i<MAC1_LEN; i++)  
-		dev->esi[i] = mac1 >>(8*(MAC1_LEN-1-i));  
-	  
-	for (i=0; i<MAC2_LEN; i++)  
-		dev->esi[i+MAC1_LEN] = mac2 >>(8*(MAC2_LEN - 1 -i));  
-	return 0;  
-}  
-	  
-static int reset_sar(struct atm_dev *dev)  
-{  
-	IADEV *iadev;  
-	int i, error;
-	unsigned int pci[64];  
-	  
-	iadev = INPH_IA_DEV(dev);  
-	for (i = 0; i < 64; i++) {
-		error = pci_read_config_dword(iadev->pci, i * 4, &pci[i]);
-		if (error != PCIBIOS_SUCCESSFUL)
-			return error;
-	}
-	writel(0, iadev->reg+IPHASE5575_EXT_RESET);  
-	for (i = 0; i < 64; i++) {
-		error = pci_write_config_dword(iadev->pci, i * 4, pci[i]);
-		if (error != PCIBIOS_SUCCESSFUL)
-			return error;
-	}
-	udelay(5);  
-	return 0;  
-}  
-	  
-	  
-static int ia_init(struct atm_dev *dev)
-{  
-	IADEV *iadev;  
-	unsigned long real_base;
-	void __iomem *base;
-	unsigned short command;  
-	int error, i; 
-	  
-	/* The device has been identified and registered. Now we read   
-	   necessary configuration info like memory base address,   
-	   interrupt number etc */  
-	  
-	IF_INIT(printk(">ia_init\n");)  
-	dev->ci_range.vpi_bits = 0;  
-	dev->ci_range.vci_bits = NR_VCI_LD;  
-
-	iadev = INPH_IA_DEV(dev);  
-	real_base = pci_resource_start (iadev->pci, 0);
-	iadev->irq = iadev->pci->irq;
-		  
-	error = pci_read_config_word(iadev->pci, PCI_COMMAND, &command);
-	if (error) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): init error 0x%x\n",  
-				dev->number,error);  
-		return -EINVAL;  
-	}  
-	IF_INIT(printk(DEV_LABEL "(itf %d): rev.%d,realbase=0x%lx,irq=%d\n",  
-			dev->number, iadev->pci->revision, real_base, iadev->irq);)
-	  
-	/* find mapping size of board */  
-	  
-	iadev->pci_map_size = pci_resource_len(iadev->pci, 0);
-
-        if (iadev->pci_map_size == 0x100000){
-          iadev->num_vc = 4096;
-	  dev->ci_range.vci_bits = NR_VCI_4K_LD;  
-          iadev->memSize = 4;
-        }
-        else if (iadev->pci_map_size == 0x40000) {
-          iadev->num_vc = 1024;
-          iadev->memSize = 1;
-        }
-        else {
-           printk("Unknown pci_map_size = 0x%x\n", iadev->pci_map_size);
-           return -EINVAL;
-        }
-	IF_INIT(printk (DEV_LABEL "map size: %i\n", iadev->pci_map_size);)  
-	  
-	/* enable bus mastering */
-	pci_set_master(iadev->pci);
-
-	/*  
-	 * Delay at least 1us before doing any mem accesses (how 'bout 10?)  
-	 */  
-	udelay(10);  
-	  
-	/* mapping the physical address to a virtual address in address space */  
-	base = ioremap(real_base,iadev->pci_map_size);  /* ioremap is not resolved ??? */  
-	  
-	if (!base)  
-	{  
-		printk(DEV_LABEL " (itf %d): can't set up page mapping\n",  
-			    dev->number);  
-		return -ENOMEM;
-	}  
-	IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n",  
-			dev->number, iadev->pci->revision, base, iadev->irq);)
-	  
-	/* filling the iphase dev structure */  
-	iadev->mem = iadev->pci_map_size /2;  
-	iadev->real_base = real_base;  
-	iadev->base = base;  
-		  
-	/* Bus Interface Control Registers */  
-	iadev->reg = base + REG_BASE;
-	/* Segmentation Control Registers */  
-	iadev->seg_reg = base + SEG_BASE;
-	/* Reassembly Control Registers */  
-	iadev->reass_reg = base + REASS_BASE;  
-	/* Front end/ DMA control registers */  
-	iadev->phy = base + PHY_BASE;  
-	iadev->dma = base + PHY_BASE;  
-	/* RAM - Segmentation RAm and Reassembly RAM */  
-	iadev->ram = base + ACTUAL_RAM_BASE;  
-	iadev->seg_ram = base + ACTUAL_SEG_RAM_BASE;  
-	iadev->reass_ram = base + ACTUAL_REASS_RAM_BASE;  
-  
-	/* lets print out the above */  
-	IF_INIT(printk("Base addrs: %p %p %p \n %p %p %p %p\n", 
-          iadev->reg,iadev->seg_reg,iadev->reass_reg, 
-          iadev->phy, iadev->ram, iadev->seg_ram, 
-          iadev->reass_ram);) 
-	  
-	/* lets try reading the MAC address */  
-	error = get_esi(dev);  
-	if (error) {
-	  iounmap(iadev->base);
-	  return error;  
-	}
-        printk("IA: ");
-	for (i=0; i < ESI_LEN; i++)  
-                printk("%s%02X",i ? "-" : "",dev->esi[i]);  
-        printk("\n");  
-  
-        /* reset SAR */  
-        if (reset_sar(dev)) {
-	   iounmap(iadev->base);
-           printk("IA: reset SAR fail, please try again\n");
-           return 1;
-        }
-	return 0;  
-}  
-
-static void ia_update_stats(IADEV *iadev) {
-    if (!iadev->carrier_detect)
-        return;
-    iadev->rx_cell_cnt += readw(iadev->reass_reg+CELL_CTR0)&0xffff;
-    iadev->rx_cell_cnt += (readw(iadev->reass_reg+CELL_CTR1) & 0xffff) << 16;
-    iadev->drop_rxpkt +=  readw(iadev->reass_reg + DRP_PKT_CNTR ) & 0xffff;
-    iadev->drop_rxcell += readw(iadev->reass_reg + ERR_CNTR) & 0xffff;
-    iadev->tx_cell_cnt += readw(iadev->seg_reg + CELL_CTR_LO_AUTO)&0xffff;
-    iadev->tx_cell_cnt += (readw(iadev->seg_reg+CELL_CTR_HIGH_AUTO)&0xffff)<<16;
-    return;
-}
-  
-static void ia_led_timer(struct timer_list *unused) {
- 	unsigned long flags;
-  	static u_char blinking[8] = {0, 0, 0, 0, 0, 0, 0, 0};
-        u_char i;
-        static u32 ctrl_reg; 
-        for (i = 0; i < iadev_count; i++) {
-           if (ia_dev[i]) {
-	      ctrl_reg = readl(ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-	      if (blinking[i] == 0) {
-		 blinking[i]++;
-                 ctrl_reg &= (~CTRL_LED);
-                 writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-                 ia_update_stats(ia_dev[i]);
-              }
-              else {
-		 blinking[i] = 0;
-		 ctrl_reg |= CTRL_LED;
-                 writel(ctrl_reg, ia_dev[i]->reg+IPHASE5575_BUS_CONTROL_REG);
-                 spin_lock_irqsave(&ia_dev[i]->tx_lock, flags);
-                 if (ia_dev[i]->close_pending)  
-                    wake_up(&ia_dev[i]->close_wait);
-                 ia_tx_poll(ia_dev[i]);
-                 spin_unlock_irqrestore(&ia_dev[i]->tx_lock, flags);
-              }
-           }
-        }
-	mod_timer(&ia_timer, jiffies + HZ / 4);
- 	return;
-}
-
-static void ia_phy_put(struct atm_dev *dev, unsigned char value,   
-	unsigned long addr)  
-{  
-	writel(value, INPH_IA_DEV(dev)->phy+addr);  
-}  
-  
-static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr)  
-{  
-	return readl(INPH_IA_DEV(dev)->phy+addr);  
-}  
-
-static void ia_free_tx(IADEV *iadev)
-{
-	int i;
-
-	kfree(iadev->desc_tbl);
-	for (i = 0; i < iadev->num_vc; i++)
-		kfree(iadev->testTable[i]);
-	kfree(iadev->testTable);
-	for (i = 0; i < iadev->num_tx_desc; i++) {
-		struct cpcs_trailer_desc *desc = iadev->tx_buf + i;
-
-		dma_unmap_single(&iadev->pci->dev, desc->dma_addr,
-				 sizeof(*desc->cpcs), DMA_TO_DEVICE);
-		kfree(desc->cpcs);
-	}
-	kfree(iadev->tx_buf);
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->tx_dle_q.start,
-			  iadev->tx_dle_dma);
-}
-
-static void ia_free_rx(IADEV *iadev)
-{
-	kfree(iadev->rx_open);
-	dma_free_coherent(&iadev->pci->dev, DLE_TOTAL_SIZE, iadev->rx_dle_q.start,
-			  iadev->rx_dle_dma);
-}
-
-static int ia_start(struct atm_dev *dev)
-{  
-	IADEV *iadev;  
-	int error;  
-	unsigned char phy;  
-	u32 ctrl_reg;  
-	IF_EVENT(printk(">ia_start\n");)  
-	iadev = INPH_IA_DEV(dev);  
-        if (request_irq(iadev->irq, &ia_int, IRQF_SHARED, DEV_LABEL, dev)) {
-                printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",  
-                    dev->number, iadev->irq);  
-		error = -EAGAIN;
-		goto err_out;
-        }  
-        /* @@@ should release IRQ on error */  
-	/* enabling memory + master */  
-        if ((error = pci_write_config_word(iadev->pci,   
-				PCI_COMMAND,   
-				PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER )))   
-	{  
-                printk(KERN_ERR DEV_LABEL "(itf %d): can't enable memory+"  
-                    "master (0x%x)\n",dev->number, error);  
-		error = -EIO;  
-		goto err_free_irq;
-        }  
-	udelay(10);  
-  
-	/* Maybe we should reset the front end, initialize Bus Interface Control   
-		Registers and see. */  
-  
-	IF_INIT(printk("Bus ctrl reg: %08x\n", 
-                            readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
-	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
-	ctrl_reg = (ctrl_reg & (CTRL_LED | CTRL_FE_RST))  
-			| CTRL_B8  
-			| CTRL_B16  
-			| CTRL_B32  
-			| CTRL_B48  
-			| CTRL_B64  
-			| CTRL_B128  
-			| CTRL_ERRMASK  
-			| CTRL_DLETMASK		/* shud be removed l8r */  
-			| CTRL_DLERMASK  
-			| CTRL_SEGMASK  
-			| CTRL_REASSMASK 	  
-			| CTRL_FEMASK  
-			| CTRL_CSPREEMPT;  
-  
-       writel(ctrl_reg, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
-  
-	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
-                           readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));  
-	   printk("Bus status reg after init: %08x\n", 
-                            readl(iadev->reg+IPHASE5575_BUS_STATUS_REG));)  
-    
-        ia_hw_type(iadev); 
-	error = tx_init(dev);  
-	if (error)
-		goto err_free_irq;
-	error = rx_init(dev);  
-	if (error)
-		goto err_free_tx;
-  
-	ctrl_reg = readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG);  
-       	writel(ctrl_reg | CTRL_FE_RST, iadev->reg+IPHASE5575_BUS_CONTROL_REG);   
-	IF_INIT(printk("Bus ctrl reg after initializing: %08x\n", 
-                               readl(iadev->reg+IPHASE5575_BUS_CONTROL_REG));)  
-        phy = 0; /* resolve compiler complaint */
-        IF_INIT ( 
-	if ((phy=ia_phy_get(dev,0)) == 0x30)  
-		printk("IA: pm5346,rev.%d\n",phy&0x0f);  
-	else  
-		printk("IA: utopia,rev.%0x\n",phy);) 
-
-	if (iadev->phy_type &  FE_25MBIT_PHY)
-           ia_mb25_init(iadev);
-	else if (iadev->phy_type & (FE_DS3_PHY | FE_E3_PHY))
-           ia_suni_pm7345_init(iadev);
-	else {
-		error = suni_init(dev);
-		if (error)
-			goto err_free_rx;
-		if (dev->phy->start) {
-			error = dev->phy->start(dev);
-			if (error)
-				goto err_free_rx;
-		}
-		/* Get iadev->carrier_detect status */
-		ia_frontend_intr(iadev);
-	}
-	return 0;
-
-err_free_rx:
-	ia_free_rx(iadev);
-err_free_tx:
-	ia_free_tx(iadev);
-err_free_irq:
-	free_irq(iadev->irq, dev);  
-err_out:
-	return error;
-}  
-  
-static void ia_close(struct atm_vcc *vcc)  
-{
-	DEFINE_WAIT(wait);
-        u16 *vc_table;
-        IADEV *iadev;
-        struct ia_vcc *ia_vcc;
-        struct sk_buff *skb = NULL;
-        struct sk_buff_head tmp_tx_backlog, tmp_vcc_backlog;
-        unsigned long closetime, flags;
-
-        iadev = INPH_IA_DEV(vcc->dev);
-        ia_vcc = INPH_IA_VCC(vcc);
-	if (!ia_vcc) return;  
-
-        IF_EVENT(printk("ia_close: ia_vcc->vc_desc_cnt = %d  vci = %d\n", 
-                                              ia_vcc->vc_desc_cnt,vcc->vci);)
-	clear_bit(ATM_VF_READY,&vcc->flags);
-        skb_queue_head_init (&tmp_tx_backlog);
-        skb_queue_head_init (&tmp_vcc_backlog); 
-        if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-           iadev->close_pending++;
-	   prepare_to_wait(&iadev->timeout_wait, &wait, TASK_UNINTERRUPTIBLE);
-	   schedule_timeout(msecs_to_jiffies(500));
-	   finish_wait(&iadev->timeout_wait, &wait);
-           spin_lock_irqsave(&iadev->tx_lock, flags); 
-           while((skb = skb_dequeue(&iadev->tx_backlog))) {
-              if (ATM_SKB(skb)->vcc == vcc){ 
-                 if (vcc->pop) vcc->pop(vcc, skb);
-                 else dev_kfree_skb_any(skb);
-              }
-              else 
-                 skb_queue_tail(&tmp_tx_backlog, skb);
-           } 
-           while((skb = skb_dequeue(&tmp_tx_backlog))) 
-             skb_queue_tail(&iadev->tx_backlog, skb);
-           IF_EVENT(printk("IA TX Done decs_cnt = %d\n", ia_vcc->vc_desc_cnt);) 
-           closetime = 300000 / ia_vcc->pcr;
-           if (closetime == 0)
-              closetime = 1;
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-           wait_event_timeout(iadev->close_wait, (ia_vcc->vc_desc_cnt <= 0), closetime);
-           spin_lock_irqsave(&iadev->tx_lock, flags);
-           iadev->close_pending--;
-           iadev->testTable[vcc->vci]->lastTime = 0;
-           iadev->testTable[vcc->vci]->fract = 0; 
-           iadev->testTable[vcc->vci]->vc_status = VC_UBR; 
-           if (vcc->qos.txtp.traffic_class == ATM_ABR) {
-              if (vcc->qos.txtp.min_pcr > 0)
-                 iadev->sum_mcr -= vcc->qos.txtp.min_pcr;
-           }
-           if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-              ia_vcc = INPH_IA_VCC(vcc); 
-              iadev->sum_mcr -= ia_vcc->NumCbrEntry*iadev->Granularity;
-              ia_cbrVc_close (vcc);
-           }
-           spin_unlock_irqrestore(&iadev->tx_lock, flags);
-        }
-        
-        if (vcc->qos.rxtp.traffic_class != ATM_NONE) {   
-           // reset reass table
-           vc_table = (u16 *)(iadev->reass_ram+REASS_TABLE*iadev->memSize);
-           vc_table += vcc->vci; 
-           *vc_table = NO_AAL5_PKT;
-           // reset vc table
-           vc_table = (u16 *)(iadev->reass_ram+RX_VC_TABLE*iadev->memSize);
-           vc_table += vcc->vci;
-           *vc_table = (vcc->vci << 6) | 15;
-           if (vcc->qos.rxtp.traffic_class == ATM_ABR) {
-              struct abr_vc_table __iomem *abr_vc_table = 
-                                (iadev->reass_ram+ABR_VC_TABLE*iadev->memSize);
-              abr_vc_table +=  vcc->vci;
-              abr_vc_table->rdf = 0x0003;
-              abr_vc_table->air = 0x5eb1;
-           }                                 
-           // Drain the packets
-           rx_dle_intr(vcc->dev); 
-           iadev->rx_open[vcc->vci] = NULL;
-        }
-	kfree(INPH_IA_VCC(vcc));  
-        ia_vcc = NULL;
-        vcc->dev_data = NULL;
-        clear_bit(ATM_VF_ADDR,&vcc->flags);
-        return;        
-}  
-  
-static int ia_open(struct atm_vcc *vcc)
-{  
-	struct ia_vcc *ia_vcc;  
-	int error;  
-	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))  
-	{  
-		IF_EVENT(printk("ia: not partially allocated resources\n");)  
-		vcc->dev_data = NULL;
-	}  
-	if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)  
-	{  
-		IF_EVENT(printk("iphase open: unspec part\n");)  
-		set_bit(ATM_VF_ADDR,&vcc->flags);
-	}  
-	if (vcc->qos.aal != ATM_AAL5)  
-		return -EINVAL;  
-	IF_EVENT(printk(DEV_LABEL "(itf %d): open %d.%d\n", 
-                                 vcc->dev->number, vcc->vpi, vcc->vci);)  
-  
-	/* Device dependent initialization */  
-	ia_vcc = kmalloc_obj(*ia_vcc);  
-	if (!ia_vcc) return -ENOMEM;  
-	vcc->dev_data = ia_vcc;
-  
-	if ((error = open_rx(vcc)))  
-	{  
-		IF_EVENT(printk("iadev: error in open_rx, closing\n");)  
-		ia_close(vcc);  
-		return error;  
-	}  
-  
-	if ((error = open_tx(vcc)))  
-	{  
-		IF_EVENT(printk("iadev: error in open_tx, closing\n");)  
-		ia_close(vcc);  
-		return error;  
-	}  
-  
-	set_bit(ATM_VF_READY,&vcc->flags);
-
-#if 0
-        {
-           static u8 first = 1; 
-           if (first) {
-              ia_timer.expires = jiffies + 3*HZ;
-              add_timer(&ia_timer);
-              first = 0;
-           }           
-        }
-#endif
-	IF_EVENT(printk("ia open returning\n");)  
-	return 0;  
-}  
-  
-static int ia_change_qos(struct atm_vcc *vcc, struct atm_qos *qos, int flags)  
-{  
-	IF_EVENT(printk(">ia_change_qos\n");)  
-	return 0;  
-}  
-  
-static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)  
-{  
-   IA_CMDBUF ia_cmds;
-   IADEV *iadev;
-   int i, board;
-   u16 __user *tmps;
-   IF_EVENT(printk(">ia_ioctl\n");)  
-   if (cmd != IA_CMD) {
-      if (!dev->phy->ioctl) return -EINVAL;
-      return dev->phy->ioctl(dev,cmd,arg);
-   }
-   if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT; 
-   board = ia_cmds.status;
-
-	if ((board < 0) || (board > iadev_count))
-		board = 0;
-	board = array_index_nospec(board, iadev_count + 1);
-
-   iadev = ia_dev[board];
-   switch (ia_cmds.cmd) {
-   case MEMDUMP:
-   {
-	switch (ia_cmds.sub_cmd) {
-          case MEMDUMP_SEGREG:
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 __user *)ia_cmds.buf;
-             for(i=0; i<0x80; i+=2, tmps++)
-                if(put_user((u16)(readl(iadev->seg_reg+i) & 0xffff), tmps)) return -EFAULT;
-             ia_cmds.status = 0;
-             ia_cmds.len = 0x80;
-             break;
-          case MEMDUMP_REASSREG:
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             tmps = (u16 __user *)ia_cmds.buf;
-             for(i=0; i<0x80; i+=2, tmps++)
-                if(put_user((u16)(readl(iadev->reass_reg+i) & 0xffff), tmps)) return -EFAULT;
-             ia_cmds.status = 0;
-             ia_cmds.len = 0x80;
-             break;
-          case MEMDUMP_FFL:
-          {  
-             ia_regs_t       *regs_local;
-             ffredn_t        *ffL;
-             rfredn_t        *rfL;
-                     
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-	     regs_local = kmalloc_obj(*regs_local);
-	     if (!regs_local) return -ENOMEM;
-	     ffL = &regs_local->ffredn;
-	     rfL = &regs_local->rfredn;
-             /* Copy real rfred registers into the local copy */
- 	     for (i=0; i<(sizeof (rfredn_t))/4; i++)
-                ((u_int *)rfL)[i] = readl(iadev->reass_reg + i) & 0xffff;
-             	/* Copy real ffred registers into the local copy */
-	     for (i=0; i<(sizeof (ffredn_t))/4; i++)
-                ((u_int *)ffL)[i] = readl(iadev->seg_reg + i) & 0xffff;
-
-             if (copy_to_user(ia_cmds.buf, regs_local,sizeof(ia_regs_t))) {
-                kfree(regs_local);
-                return -EFAULT;
-             }
-             kfree(regs_local);
-             printk("Board %d registers dumped\n", board);
-             ia_cmds.status = 0;                  
-	 }	
-    	     break;        
-         case READ_REG:
-         {  
-	     if (!capable(CAP_NET_ADMIN)) return -EPERM;
-             desc_dbg(iadev); 
-             ia_cmds.status = 0; 
-         }
-             break;
-         case 0x6:
-         {  
-             ia_cmds.status = 0; 
-             printk("skb = 0x%p\n", skb_peek(&iadev->tx_backlog));
-             printk("rtn_q: 0x%p\n",ia_deque_rtn_q(&iadev->tx_return_q));
-         }
-             break;
-         case 0x8:
-         {
-             struct k_sonet_stats *stats;
-             stats = &PRIV(_ia_dev[board])->sonet_stats;
-             printk("section_bip: %d\n", atomic_read(&stats->section_bip));
-             printk("line_bip   : %d\n", atomic_read(&stats->line_bip));
-             printk("path_bip   : %d\n", atomic_read(&stats->path_bip));
-             printk("line_febe  : %d\n", atomic_read(&stats->line_febe));
-             printk("path_febe  : %d\n", atomic_read(&stats->path_febe));
-             printk("corr_hcs   : %d\n", atomic_read(&stats->corr_hcs));
-             printk("uncorr_hcs : %d\n", atomic_read(&stats->uncorr_hcs));
-             printk("tx_cells   : %d\n", atomic_read(&stats->tx_cells));
-             printk("rx_cells   : %d\n", atomic_read(&stats->rx_cells));
-         }
-            ia_cmds.status = 0;
-            break;
-         case 0x9:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            for (i = 1; i <= iadev->num_rx_desc; i++)
-               free_desc(_ia_dev[board], i);
-            writew( ~(RX_FREEQ_EMPT | RX_EXCP_RCVD), 
-                                            iadev->reass_reg+REASS_MASK_REG);
-            iadev->rxing = 1;
-            
-            ia_cmds.status = 0;
-            break;
-
-         case 0xb:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            ia_frontend_intr(iadev);
-            break;
-         case 0xa:
-	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-         {  
-             ia_cmds.status = 0; 
-             IADebugFlag = ia_cmds.maddr;
-             printk("New debug option loaded\n");
-         }
-             break;
-         default:
-             ia_cmds.status = 0;
-             break;
-      }	
-   }
-      break;
-   default:
-      break;
-
-   }	
-   return 0;  
-}  
-  
-static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) {
-        IADEV *iadev;
-        struct dle *wr_ptr;
-        struct tx_buf_desc __iomem *buf_desc_ptr;
-        int desc;
-        int comp_code;
-        int total_len;
-        struct cpcs_trailer *trailer;
-        struct ia_vcc *iavcc;
-
-        iadev = INPH_IA_DEV(vcc->dev);  
-        iavcc = INPH_IA_VCC(vcc);
-        if (!iavcc->txing) {
-           printk("discard packet on closed VC\n");
-           if (vcc->pop)
-		vcc->pop(vcc, skb);
-           else
-		dev_kfree_skb_any(skb);
-	   return 0;
-        }
-
-        if (skb->len > iadev->tx_buf_sz - 8) {
-           printk("Transmit size over tx buffer size\n");
-           if (vcc->pop)
-                 vcc->pop(vcc, skb);
-           else
-                 dev_kfree_skb_any(skb);
-          return 0;
-        }
-        if ((unsigned long)skb->data & 3) {
-           printk("Misaligned SKB\n");
-           if (vcc->pop)
-                 vcc->pop(vcc, skb);
-           else
-                 dev_kfree_skb_any(skb);
-           return 0;
-        }       
-	/* Get a descriptor number from our free descriptor queue  
-	   We get the descr number from the TCQ now, since I am using  
-	   the TCQ as a free buffer queue. Initially TCQ will be   
-	   initialized with all the descriptors and is hence, full.  
-	*/
-	desc = get_desc (iadev, iavcc);
-	if (desc == 0xffff) 
-	    return 1;
-	comp_code = desc >> 13;  
-	desc &= 0x1fff;  
-  
-	if ((desc == 0) || (desc > iadev->num_tx_desc))  
-	{  
-		IF_ERR(printk(DEV_LABEL "invalid desc for send: %d\n", desc);) 
-                atomic_inc(&vcc->stats->tx);
-		if (vcc->pop)   
-		    vcc->pop(vcc, skb);   
-		else  
-		    dev_kfree_skb_any(skb);
-		return 0;   /* return SUCCESS */
-	}  
-  
-	if (comp_code)  
-	{  
-	    IF_ERR(printk(DEV_LABEL "send desc:%d completion code %d error\n", 
-                                                            desc, comp_code);)  
-	}  
-       
-        /* remember the desc and vcc mapping */
-        iavcc->vc_desc_cnt++;
-        iadev->desc_tbl[desc-1].iavcc = iavcc;
-        iadev->desc_tbl[desc-1].txskb = skb;
-        IA_SKB_STATE(skb) = 0;
-
-        iadev->ffL.tcq_rd += 2;
-        if (iadev->ffL.tcq_rd > iadev->ffL.tcq_ed)
-	  	iadev->ffL.tcq_rd  = iadev->ffL.tcq_st;
-	writew(iadev->ffL.tcq_rd, iadev->seg_reg+TCQ_RD_PTR);
-  
-	/* Put the descriptor number in the packet ready queue  
-		and put the updated write pointer in the DLE field   
-	*/   
-	*(u16*)(iadev->seg_ram+iadev->ffL.prq_wr) = desc; 
-
- 	iadev->ffL.prq_wr += 2;
-        if (iadev->ffL.prq_wr > iadev->ffL.prq_ed)
-                iadev->ffL.prq_wr = iadev->ffL.prq_st;
-	  
-	/* Figure out the exact length of the packet and padding required to 
-           make it  aligned on a 48 byte boundary.  */
-	total_len = skb->len + sizeof(struct cpcs_trailer);  
-	total_len = ((total_len + 47) / 48) * 48;
-	IF_TX(printk("ia packet len:%d padding:%d\n", total_len, total_len - skb->len);)  
- 
-	/* Put the packet in a tx buffer */   
-	trailer = iadev->tx_buf[desc-1].cpcs;
-        IF_TX(printk("Sent: skb = 0x%p skb->data: 0x%p len: %d, desc: %d\n",
-                  skb, skb->data, skb->len, desc);)
-	trailer->control = 0; 
-        /*big endian*/ 
-	trailer->length = ((skb->len & 0xff) << 8) | ((skb->len & 0xff00) >> 8);
-	trailer->crc32 = 0;	/* not needed - dummy bytes */  
-
-	/* Display the packet */  
-	IF_TXPKT(printk("Sent data: len = %d MsgNum = %d\n", 
-                                                        skb->len, tcnter++);  
-        xdump(skb->data, skb->len, "TX: ");
-        printk("\n");)
-
-	/* Build the buffer descriptor */  
-	buf_desc_ptr = iadev->seg_ram+TX_DESC_BASE;
-	buf_desc_ptr += desc;	/* points to the corresponding entry */  
-	buf_desc_ptr->desc_mode = AAL5 | EOM_EN | APP_CRC32 | CMPL_INT;   
-	/* Huh ? p.115 of users guide describes this as a read-only register */
-        writew(TRANSMIT_DONE, iadev->seg_reg+SEG_INTR_STATUS_REG);
-	buf_desc_ptr->vc_index = vcc->vci;
-	buf_desc_ptr->bytes = total_len;  
-
-        if (vcc->qos.txtp.traffic_class == ATM_ABR)  
-	   clear_lockup (vcc, iadev);
-
-	/* Build the DLE structure */  
-	wr_ptr = iadev->tx_dle_q.write;  
-	memset((caddr_t)wr_ptr, 0, sizeof(*wr_ptr));  
-	wr_ptr->sys_pkt_addr = dma_map_single(&iadev->pci->dev, skb->data,
-					      skb->len, DMA_TO_DEVICE);
-	wr_ptr->local_pkt_addr = (buf_desc_ptr->buf_start_hi << 16) | 
-                                                  buf_desc_ptr->buf_start_lo;  
-	/* wr_ptr->bytes = swap_byte_order(total_len); didn't seem to affect?? */
-	wr_ptr->bytes = skb->len;  
-
-        /* hw bug - DLEs of 0x2d, 0x2e, 0x2f cause DMA lockup */
-        if ((wr_ptr->bytes >> 2) == 0xb)
-           wr_ptr->bytes = 0x30;
-
-	wr_ptr->mode = TX_DLE_PSI; 
-	wr_ptr->prq_wr_ptr_data = 0;
-  
-	/* end is not to be used for the DLE q */  
-	if (++wr_ptr == iadev->tx_dle_q.end)  
-		wr_ptr = iadev->tx_dle_q.start;  
-        
-        /* Build trailer dle */
-        wr_ptr->sys_pkt_addr = iadev->tx_buf[desc-1].dma_addr;
-        wr_ptr->local_pkt_addr = ((buf_desc_ptr->buf_start_hi << 16) | 
-          buf_desc_ptr->buf_start_lo) + total_len - sizeof(struct cpcs_trailer);
-
-        wr_ptr->bytes = sizeof(struct cpcs_trailer);
-        wr_ptr->mode = DMA_INT_ENABLE; 
-        wr_ptr->prq_wr_ptr_data = iadev->ffL.prq_wr;
-        
-        /* end is not to be used for the DLE q */
-        if (++wr_ptr == iadev->tx_dle_q.end)  
-                wr_ptr = iadev->tx_dle_q.start;
-
-	iadev->tx_dle_q.write = wr_ptr;  
-        ATM_DESC(skb) = vcc->vci;
-        skb_queue_tail(&iadev->tx_dma_q, skb);
-
-        atomic_inc(&vcc->stats->tx);
-        iadev->tx_pkt_cnt++;
-	/* Increment transaction counter */  
-	writel(2, iadev->dma+IPHASE5575_TX_COUNTER);  
-        
-#if 0        
-        /* add flow control logic */ 
-        if (atomic_read(&vcc->stats->tx) % 20 == 0) {
-          if (iavcc->vc_desc_cnt > 10) {
-             vcc->tx_quota =  vcc->tx_quota * 3 / 4;
-            printk("Tx1:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota );
-              iavcc->flow_inc = -1;
-              iavcc->saved_tx_quota = vcc->tx_quota;
-           } else if ((iavcc->flow_inc < 0) && (iavcc->vc_desc_cnt < 3)) {
-             // vcc->tx_quota = 3 * iavcc->saved_tx_quota / 4;
-             printk("Tx2:  vcc->tx_quota = %d \n", (u32)vcc->tx_quota ); 
-              iavcc->flow_inc = 0;
-           }
-        }
-#endif
-	IF_TX(printk("ia send done\n");)  
-	return 0;  
-}  
-
-static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-        IADEV *iadev; 
-        unsigned long flags;
-
-        iadev = INPH_IA_DEV(vcc->dev);
-        if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
-        {
-            if (!skb)
-                printk(KERN_CRIT "null skb in ia_send\n");
-            else dev_kfree_skb_any(skb);
-            return -EINVAL;
-        }                         
-        spin_lock_irqsave(&iadev->tx_lock, flags); 
-        if (!test_bit(ATM_VF_READY,&vcc->flags)){ 
-            dev_kfree_skb_any(skb);
-            spin_unlock_irqrestore(&iadev->tx_lock, flags);
-            return -EINVAL; 
-        }
-        ATM_SKB(skb)->vcc = vcc;
- 
-        if (skb_peek(&iadev->tx_backlog)) {
-           skb_queue_tail(&iadev->tx_backlog, skb);
-        }
-        else {
-           if (ia_pkt_tx (vcc, skb)) {
-              skb_queue_tail(&iadev->tx_backlog, skb);
-           }
-        }
-        spin_unlock_irqrestore(&iadev->tx_lock, flags);
-        return 0;
-
-}
-
-static int ia_proc_read(struct atm_dev *dev,loff_t *pos,char *page)
-{ 
-  int   left = *pos, n;   
-  char  *tmpPtr;
-  IADEV *iadev = INPH_IA_DEV(dev);
-  if(!left--) {
-     if (iadev->phy_type == FE_25MBIT_PHY) {
-       n = sprintf(page, "  Board Type         :  Iphase5525-1KVC-128K\n");
-       return n;
-     }
-     if (iadev->phy_type == FE_DS3_PHY)
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-DS3");
-     else if (iadev->phy_type == FE_E3_PHY)
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-E3");
-     else if (iadev->phy_type == FE_UTP_OPTION)
-         n = sprintf(page, "  Board Type         :  Iphase-ATM-UTP155"); 
-     else
-        n = sprintf(page, "  Board Type         :  Iphase-ATM-OC3");
-     tmpPtr = page + n;
-     if (iadev->pci_map_size == 0x40000)
-        n += sprintf(tmpPtr, "-1KVC-");
-     else
-        n += sprintf(tmpPtr, "-4KVC-");  
-     tmpPtr = page + n; 
-     if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_1M)
-        n += sprintf(tmpPtr, "1M  \n");
-     else if ((iadev->memType & MEM_SIZE_MASK) == MEM_SIZE_512K)
-        n += sprintf(tmpPtr, "512K\n");
-     else
-       n += sprintf(tmpPtr, "128K\n");
-     return n;
-  }
-  if (!left) {
-     return  sprintf(page, "  Number of Tx Buffer:  %u\n"
-                           "  Size of Tx Buffer  :  %u\n"
-                           "  Number of Rx Buffer:  %u\n"
-                           "  Size of Rx Buffer  :  %u\n"
-                           "  Packets Received   :  %u\n"
-                           "  Packets Transmitted:  %u\n"
-                           "  Cells Received     :  %u\n"
-                           "  Cells Transmitted  :  %u\n"
-                           "  Board Dropped Cells:  %u\n"
-                           "  Board Dropped Pkts :  %u\n",
-                           iadev->num_tx_desc,  iadev->tx_buf_sz,
-                           iadev->num_rx_desc,  iadev->rx_buf_sz,
-                           iadev->rx_pkt_cnt,   iadev->tx_pkt_cnt,
-                           iadev->rx_cell_cnt, iadev->tx_cell_cnt,
-                           iadev->drop_rxcell, iadev->drop_rxpkt);                        
-  }
-  return 0;
-}
-  
-static const struct atmdev_ops ops = {  
-	.open		= ia_open,  
-	.close		= ia_close,  
-	.ioctl		= ia_ioctl,  
-	.send		= ia_send,  
-	.phy_put	= ia_phy_put,  
-	.phy_get	= ia_phy_get,  
-	.change_qos	= ia_change_qos,  
-	.proc_read	= ia_proc_read,
-	.owner		= THIS_MODULE,
-};  
-	  
-static int ia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{  
-	struct atm_dev *dev;  
-	IADEV *iadev;  
-	int ret;
-
-	iadev = kzalloc_obj(*iadev);
-	if (!iadev) {
-		ret = -ENOMEM;
-		goto err_out;
-	}
-
-	iadev->pci = pdev;
-
-	IF_INIT(printk("ia detected at bus:%d dev: %d function:%d\n",
-		pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));)
-	if (pci_enable_device(pdev)) {
-		ret = -ENODEV;
-		goto err_out_free_iadev;
-	}
-	dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL);
-	if (!dev) {
-		ret = -ENOMEM;
-		goto err_out_disable_dev;
-	}
-	dev->dev_data = iadev;
-	IF_INIT(printk(DEV_LABEL "registered at (itf :%d)\n", dev->number);)
-	IF_INIT(printk("dev_id = 0x%p iadev->LineRate = %d \n", dev,
-		iadev->LineRate);)
-
-	pci_set_drvdata(pdev, dev);
-
-	ia_dev[iadev_count] = iadev;
-	_ia_dev[iadev_count] = dev;
-	iadev_count++;
-	if (ia_init(dev) || ia_start(dev)) {  
-		IF_INIT(printk("IA register failed!\n");)
-		iadev_count--;
-		ia_dev[iadev_count] = NULL;
-		_ia_dev[iadev_count] = NULL;
-		ret = -EINVAL;
-		goto err_out_deregister_dev;
-	}
-	IF_EVENT(printk("iadev_count = %d\n", iadev_count);)
-
-	iadev->next_board = ia_boards;  
-	ia_boards = dev;  
-
-	return 0;
-
-err_out_deregister_dev:
-	atm_dev_deregister(dev);  
-err_out_disable_dev:
-	pci_disable_device(pdev);
-err_out_free_iadev:
-	kfree(iadev);
-err_out:
-	return ret;
-}
-
-static void ia_remove_one(struct pci_dev *pdev)
-{
-	struct atm_dev *dev = pci_get_drvdata(pdev);
-	IADEV *iadev = INPH_IA_DEV(dev);
-
-	/* Disable phy interrupts */
-	ia_phy_put(dev, ia_phy_get(dev, SUNI_RSOP_CIE) & ~(SUNI_RSOP_CIE_LOSE),
-				   SUNI_RSOP_CIE);
-	udelay(1);
-
-	if (dev->phy && dev->phy->stop)
-		dev->phy->stop(dev);
-
-	/* De-register device */  
-      	free_irq(iadev->irq, dev);
-	iadev_count--;
-	ia_dev[iadev_count] = NULL;
-	_ia_dev[iadev_count] = NULL;
-	IF_EVENT(printk("deregistering iav at (itf:%d)\n", dev->number);)
-	atm_dev_deregister(dev);
-
-      	iounmap(iadev->base);  
-	pci_disable_device(pdev);
-
-	ia_free_rx(iadev);
-	ia_free_tx(iadev);
-
-      	kfree(iadev);
-}
-
-static const struct pci_device_id ia_pci_tbl[] = {
-	{ PCI_VENDOR_ID_IPHASE, 0x0008, PCI_ANY_ID, PCI_ANY_ID, },
-	{ PCI_VENDOR_ID_IPHASE, 0x0009, PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0,}
-};
-MODULE_DEVICE_TABLE(pci, ia_pci_tbl);
-
-static struct pci_driver ia_driver = {
-	.name =         DEV_LABEL,
-	.id_table =     ia_pci_tbl,
-	.probe =        ia_init_one,
-	.remove =       ia_remove_one,
-};
-
-static int __init ia_module_init(void)
-{
-	int ret;
-
-	ret = pci_register_driver(&ia_driver);
-	if (ret >= 0) {
-		ia_timer.expires = jiffies + 3*HZ;
-		add_timer(&ia_timer); 
-	} else
-		printk(KERN_ERR DEV_LABEL ": no adapter found\n");  
-	return ret;
-}
-
-static void __exit ia_module_exit(void)
-{
-	pci_unregister_driver(&ia_driver);
-
-	timer_delete_sync(&ia_timer);
-}
-
-module_init(ia_module_init);
-module_exit(ia_module_exit);
diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h
deleted file mode 100644
index 2f5f887..0000000
--- a/drivers/atm/iphase.h
+++ /dev/null
@@ -1,1452 +0,0 @@
-/******************************************************************************
-             Device driver for Interphase ATM PCI adapter cards 
-                    Author: Peter Wang  <pwang@iphase.com>            
-                   Interphase Corporation  <www.iphase.com>           
-                               Version: 1.0   
-               iphase.h:  This is the header file for iphase.c. 
-*******************************************************************************
-      
-      This software may be used and distributed according to the terms
-      of the GNU General Public License (GPL), incorporated herein by reference.
-      Drivers based on this skeleton fall under the GPL and must retain
-      the authorship (implicit copyright) notice.
-
-      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.
-      
-      Modified from an incomplete driver for Interphase 5575 1KVC 1M card which 
-      was originally written by Monalisa Agrawal at UNH. Now this driver 
-      supports a variety of varients of Interphase ATM PCI (i)Chip adapter 
-      card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) 
-      in terms of PHY type, the size of control memory and the size of 
-      packet memory. The following are the change log and history:
-     
-          Bugfix the Mona's UBR driver.
-          Modify the basic memory allocation and dma logic.
-          Port the driver to the latest kernel from 2.0.46.
-          Complete the ABR logic of the driver, and added the ABR work-
-              around for the hardware anormalies.
-          Add the CBR support.
-	  Add the flow control logic to the driver to allow rate-limit VC.
-          Add 4K VC support to the board with 512K control memory.
-          Add the support of all the variants of the Interphase ATM PCI 
-          (i)Chip adapter cards including x575 (155M OC3 and UTP155), x525
-          (25M UTP25) and x531 (DS3 and E3).
-          Add SMP support.
-
-      Support and updates available at: ftp://ftp.iphase.com/pub/atm
-
-*******************************************************************************/
-  
-#ifndef IPHASE_H  
-#define IPHASE_H  
-
-
-/************************ IADBG DEFINE *********************************/
-/* IADebugFlag Bit Map */ 
-#define IF_IADBG_INIT_ADAPTER   0x00000001        // init adapter info
-#define IF_IADBG_TX             0x00000002        // debug TX
-#define IF_IADBG_RX             0x00000004        // debug RX
-#define IF_IADBG_QUERY_INFO     0x00000008        // debug Request call
-#define IF_IADBG_SHUTDOWN       0x00000010        // debug shutdown event
-#define IF_IADBG_INTR           0x00000020        // debug interrupt DPC
-#define IF_IADBG_TXPKT          0x00000040  	  // debug TX PKT
-#define IF_IADBG_RXPKT          0x00000080  	  // debug RX PKT
-#define IF_IADBG_ERR            0x00000100        // debug system error
-#define IF_IADBG_EVENT          0x00000200        // debug event
-#define IF_IADBG_DIS_INTR       0x00001000        // debug disable interrupt
-#define IF_IADBG_EN_INTR        0x00002000        // debug enable interrupt
-#define IF_IADBG_LOUD           0x00004000        // debugging info
-#define IF_IADBG_VERY_LOUD      0x00008000        // excessive debugging info
-#define IF_IADBG_CBR            0x00100000  	  //
-#define IF_IADBG_UBR            0x00200000  	  //
-#define IF_IADBG_ABR            0x00400000        //
-#define IF_IADBG_DESC           0x01000000        //
-#define IF_IADBG_SUNI_STAT      0x02000000        // suni statistics
-#define IF_IADBG_RESET          0x04000000        
-
-#define IF_IADBG(f) if (IADebugFlag & (f))
-
-#ifdef  CONFIG_ATM_IA_DEBUG   /* Debug build */
-
-#define IF_LOUD(A) IF_IADBG(IF_IADBG_LOUD) { A }
-#define IF_ERR(A) IF_IADBG(IF_IADBG_ERR) { A }
-#define IF_VERY_LOUD(A) IF_IADBG( IF_IADBG_VERY_LOUD ) { A }
-
-#define IF_INIT_ADAPTER(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A }
-#define IF_INIT(A) IF_IADBG( IF_IADBG_INIT_ADAPTER ) { A }
-#define IF_SUNI_STAT(A) IF_IADBG( IF_IADBG_SUNI_STAT ) { A }
-#define IF_QUERY_INFO(A) IF_IADBG( IF_IADBG_QUERY_INFO ) { A }
-#define IF_COPY_OVER(A) IF_IADBG( IF_IADBG_COPY_OVER ) { A }
-
-#define IF_INTR(A) IF_IADBG( IF_IADBG_INTR ) { A }
-#define IF_DIS_INTR(A) IF_IADBG( IF_IADBG_DIS_INTR ) { A }
-#define IF_EN_INTR(A) IF_IADBG( IF_IADBG_EN_INTR ) { A }
-
-#define IF_TX(A) IF_IADBG( IF_IADBG_TX ) { A }
-#define IF_RX(A) IF_IADBG( IF_IADBG_RX ) { A }
-#define IF_TXPKT(A) IF_IADBG( IF_IADBG_TXPKT ) { A }
-#define IF_RXPKT(A) IF_IADBG( IF_IADBG_RXPKT ) { A }
-
-#define IF_SHUTDOWN(A) IF_IADBG(IF_IADBG_SHUTDOWN) { A }
-#define IF_CBR(A) IF_IADBG( IF_IADBG_CBR ) { A }
-#define IF_UBR(A) IF_IADBG( IF_IADBG_UBR ) { A }
-#define IF_ABR(A) IF_IADBG( IF_IADBG_ABR ) { A }
-#define IF_EVENT(A) IF_IADBG( IF_IADBG_EVENT) { A }
-
-#else /* free build */
-#define IF_LOUD(A)
-#define IF_VERY_LOUD(A)
-#define IF_INIT_ADAPTER(A)
-#define IF_INIT(A)
-#define IF_SUNI_STAT(A)
-#define IF_PVC_CHKPKT(A)
-#define IF_QUERY_INFO(A)
-#define IF_COPY_OVER(A)
-#define IF_HANG(A)
-#define IF_INTR(A)
-#define IF_DIS_INTR(A)
-#define IF_EN_INTR(A)
-#define IF_TX(A)
-#define IF_RX(A)
-#define IF_TXDEBUG(A)
-#define IF_VC(A)
-#define IF_ERR(A) 
-#define IF_CBR(A)
-#define IF_UBR(A)
-#define IF_ABR(A)
-#define IF_SHUTDOWN(A)
-#define DbgPrint(A)
-#define IF_EVENT(A)
-#define IF_TXPKT(A) 
-#define IF_RXPKT(A)
-#endif /* CONFIG_ATM_IA_DEBUG */ 
-
-#define ATM_DESC(skb) (skb->protocol)
-#define IA_SKB_STATE(skb) (skb->protocol)
-#define IA_DLED   1
-#define IA_TX_DONE 2
-
-/* iadbg defines */
-#define IA_CMD   0x7749
-typedef struct {
-	int cmd;
-        int sub_cmd;
-        int len;
-        u32 maddr;
-        int status;
-        void __user *buf;
-} IA_CMDBUF, *PIA_CMDBUF;
-
-/* cmds */
-#define MEMDUMP     		0x01
-
-/* sub_cmds */
-#define MEMDUMP_SEGREG          0x2
-#define MEMDUMP_DEV  		0x1
-#define MEMDUMP_REASSREG        0x3
-#define MEMDUMP_FFL             0x4
-#define READ_REG                0x5
-#define WAKE_DBG_WAIT           0x6
-
-/************************ IADBG DEFINE END ***************************/
-
-#define Boolean(x)    	((x) ? 1 : 0)
-#define NR_VCI 1024		/* number of VCIs */  
-#define NR_VCI_LD 10		/* log2(NR_VCI) */  
-#define NR_VCI_4K 4096 		/* number of VCIs */  
-#define NR_VCI_4K_LD 12		/* log2(NR_VCI) */  
-#define MEM_VALID 0xfffffff0	/* mask base address with this */  
-  
-#ifndef PCI_VENDOR_ID_IPHASE  
-#define PCI_VENDOR_ID_IPHASE 0x107e  
-#endif  
-#ifndef PCI_DEVICE_ID_IPHASE_5575  
-#define PCI_DEVICE_ID_IPHASE_5575 0x0008  
-#endif  
-#define DEV_LABEL 	"ia"  
-#define PCR	207692  
-#define ICR	100000  
-#define MCR	0  
-#define TBE	1000  
-#define FRTT	1  
-#define RIF	2		  
-#define RDF	4  
-#define NRMCODE 5	/* 0 - 7 */  
-#define TRMCODE	3	/* 0 - 7 */  
-#define CDFCODE	6  
-#define ATDFCODE 2	/* 0 - 15 */  
-  
-/*---------------------- Packet/Cell Memory ------------------------*/  
-#define TX_PACKET_RAM 	0x00000 /* start of Trasnmit Packet memory - 0 */  
-#define DFL_TX_BUF_SZ	10240	/* 10 K buffers */  
-#define DFL_TX_BUFFERS     50 	/* number of packet buffers for Tx   
-					- descriptor 0 unused */  
-#define REASS_RAM_SIZE 0x10000  /* for 64K 1K VC board */  
-#define RX_PACKET_RAM 	0x80000 /* start of Receive Packet memory - 512K */  
-#define DFL_RX_BUF_SZ	10240	/* 10k buffers */  
-#define DFL_RX_BUFFERS      50	/* number of packet buffers for Rx   
-					- descriptor 0 unused */  
-  
-struct cpcs_trailer 
-{  
-	u_short control;  
-	u_short length;  
-	u_int	crc32;  
-};  
-
-struct cpcs_trailer_desc
-{
-	struct cpcs_trailer *cpcs;
-	dma_addr_t dma_addr;
-};
-
-struct ia_vcc 
-{ 
-	int rxing;	 
-	int txing;		 
-        int NumCbrEntry;
-        u32 pcr;
-        u32 saved_tx_quota;
-        int flow_inc;
-        struct sk_buff_head txing_skb; 
-        int  ltimeout;                  
-        u8  vc_desc_cnt;                
-                
-};  
-  
-struct abr_vc_table 
-{  
-	u_char status;  
-	u_char rdf;  
-	u_short air;  
-	u_int res[3];  
-	u_int req_rm_cell_data1;  
-	u_int req_rm_cell_data2;  
-	u_int add_rm_cell_data1;  
-	u_int add_rm_cell_data2;  
-};  
-    
-/* 32 byte entries */  
-struct main_vc 
-{  
-	u_short 	type;  
-#define ABR	0x8000  
-#define UBR 	0xc000  
-#define CBR	0x0000  
-	/* ABR fields */  
-	u_short 	nrm;	 
- 	u_short 	trm;	   
-	u_short 	rm_timestamp_hi;  
-	u_short 	rm_timestamp_lo:8,  
-			crm:8;		  
-	u_short 	remainder; 	/* ABR and UBR fields - last 10 bits*/  
-	u_short 	next_vc_sched;  
-	u_short 	present_desc;	/* all classes */  
-	u_short 	last_cell_slot;	/* ABR and UBR */  
-	u_short 	pcr;  
-	u_short 	fraction;  
-	u_short 	icr;  
-	u_short 	atdf;  
-	u_short 	mcr;  
-	u_short 	acr;		 
-	u_short 	unack:8,  
-			status:8;	/* all classes */  
-#define UIOLI 0x80  
-#define CRC_APPEND 0x40			/* for status field - CRC-32 append */  
-#define ABR_STATE 0x02  
-  
-};  
-  
-  
-/* 8 byte entries */  
-struct ext_vc 
-{  
-	u_short 	atm_hdr1;  
-	u_short 	atm_hdr2;  
-	u_short 	last_desc;  
-      	u_short 	out_of_rate_link;   /* reserved for UBR and CBR */  
-};  
-  
-  
-#define DLE_ENTRIES 256  
-#define DMA_INT_ENABLE 0x0002	/* use for both Tx and Rx */  
-#define TX_DLE_PSI 0x0001  
-#define DLE_TOTAL_SIZE (sizeof(struct dle)*DLE_ENTRIES)
-  
-/* Descriptor List Entries (DLE) */  
-struct dle 
-{  
-	u32 	sys_pkt_addr;  
-	u32 	local_pkt_addr;  
-	u32 	bytes;  
-	u16 	prq_wr_ptr_data;  
-	u16 	mode;  
-};  
-  
-struct dle_q 
-{  
-	struct dle 	*start;  
-	struct dle 	*end;  
-	struct dle 	*read;  
-	struct dle 	*write;  
-};  
-  
-struct free_desc_q 
-{  
-	int 	desc;	/* Descriptor number */  
-	struct free_desc_q *next;  
-};  
-  
-struct tx_buf_desc {  
-	unsigned short desc_mode;  
-	unsigned short vc_index;  
-	unsigned short res1;		/* reserved field */  
-	unsigned short bytes;  
-	unsigned short buf_start_hi;  
-	unsigned short buf_start_lo;  
-	unsigned short res2[10];	/* reserved field */  
-};  
-	  
-  
-struct rx_buf_desc { 
-	unsigned short desc_mode;
-	unsigned short vc_index;
-	unsigned short vpi; 
-	unsigned short bytes; 
-	unsigned short buf_start_hi;  
-	unsigned short buf_start_lo;  
-	unsigned short dma_start_hi;  
-	unsigned short dma_start_lo;  
-	unsigned short crc_upper;  
-	unsigned short crc_lower;  
-	unsigned short res:8, timeout:8;  
-	unsigned short res2[5];	/* reserved field */  
-};  
-  
-/*--------SAR stuff ---------------------*/  
-  
-#define EPROM_SIZE 0x40000	/* says 64K in the docs ??? */  
-#define MAC1_LEN	4	   					  
-#define MAC2_LEN	2  
-   
-/*------------ PCI Memory Space Map, 128K SAR memory ----------------*/  
-#define IPHASE5575_PCI_CONFIG_REG_BASE	0x0000  
-#define IPHASE5575_BUS_CONTROL_REG_BASE 0x1000	/* offsets 0x00 - 0x3c */  
-#define IPHASE5575_FRAG_CONTROL_REG_BASE 0x2000  
-#define IPHASE5575_REASS_CONTROL_REG_BASE 0x3000  
-#define IPHASE5575_DMA_CONTROL_REG_BASE	0x4000  
-#define IPHASE5575_FRONT_END_REG_BASE IPHASE5575_DMA_CONTROL_REG_BASE  
-#define IPHASE5575_FRAG_CONTROL_RAM_BASE 0x10000  
-#define IPHASE5575_REASS_CONTROL_RAM_BASE 0x20000  
-  
-/*------------ Bus interface control registers -----------------*/  
-#define IPHASE5575_BUS_CONTROL_REG	0x00  
-#define IPHASE5575_BUS_STATUS_REG	0x01	/* actual offset 0x04 */  
-#define IPHASE5575_MAC1			0x02  
-#define IPHASE5575_REV			0x03  
-#define IPHASE5575_MAC2			0x03	/*actual offset 0x0e-reg 0x0c*/  
-#define IPHASE5575_EXT_RESET		0x04  
-#define IPHASE5575_INT_RESET		0x05	/* addr 1c ?? reg 0x06 */  
-#define IPHASE5575_PCI_ADDR_PAGE	0x07	/* reg 0x08, 0x09 ?? */  
-#define IPHASE5575_EEPROM_ACCESS	0x0a	/* actual offset 0x28 */  
-#define IPHASE5575_CELL_FIFO_QUEUE_SZ	0x0b  
-#define IPHASE5575_CELL_FIFO_MARK_STATE	0x0c  
-#define IPHASE5575_CELL_FIFO_READ_PTR	0x0d  
-#define IPHASE5575_CELL_FIFO_WRITE_PTR	0x0e  
-#define IPHASE5575_CELL_FIFO_CELLS_AVL	0x0f	/* actual offset 0x3c */  
-  
-/* Bus Interface Control Register bits */  
-#define CTRL_FE_RST	0x80000000  
-#define CTRL_LED	0x40000000  
-#define CTRL_25MBPHY	0x10000000  
-#define CTRL_ENCMBMEM	0x08000000  
-#define CTRL_ENOFFSEG	0x01000000  
-#define CTRL_ERRMASK	0x00400000  
-#define CTRL_DLETMASK	0x00100000  
-#define CTRL_DLERMASK	0x00080000  
-#define CTRL_FEMASK	0x00040000  
-#define CTRL_SEGMASK	0x00020000  
-#define CTRL_REASSMASK	0x00010000  
-#define CTRL_CSPREEMPT	0x00002000  
-#define CTRL_B128	0x00000200  
-#define CTRL_B64	0x00000100  
-#define CTRL_B48	0x00000080  
-#define CTRL_B32	0x00000040  
-#define CTRL_B16	0x00000020  
-#define CTRL_B8		0x00000010  
-  
-/* Bus Interface Status Register bits */  
-#define STAT_CMEMSIZ	0xc0000000  
-#define STAT_ADPARCK	0x20000000  
-#define STAT_RESVD	0x1fffff80  
-#define STAT_ERRINT	0x00000040  
-#define STAT_MARKINT	0x00000020  
-#define STAT_DLETINT	0x00000010  
-#define STAT_DLERINT	0x00000008  
-#define STAT_FEINT	0x00000004  
-#define STAT_SEGINT	0x00000002  
-#define STAT_REASSINT	0x00000001  
-  
-  
-/*--------------- Segmentation control registers -----------------*/  
-/* The segmentation registers are 16 bits access and the addresses  
-	are defined as such so the addresses are the actual "offsets" */  
-#define IDLEHEADHI	0x00  
-#define IDLEHEADLO	0x01  
-#define MAXRATE		0x02  
-/* Values for MAXRATE register for 155Mbps and 25.6 Mbps operation */  
-#define RATE155		0x64b1 // 16 bits float format 
-#define MAX_ATM_155     352768 // Cells/second p.118
-#define RATE25		0x5f9d  
-  
-#define STPARMS		0x03  
-#define STPARMS_1K	0x008c  
-#define STPARMS_2K	0x0049  
-#define STPARMS_4K	0x0026  
-#define COMP_EN		0x4000  
-#define CBR_EN		0x2000  
-#define ABR_EN		0x0800  
-#define UBR_EN		0x0400  
-  
-#define ABRUBR_ARB	0x04  
-#define RM_TYPE		0x05  
-/*Value for RM_TYPE register for ATM Forum Traffic Mangement4.0 support*/  
-#define RM_TYPE_4_0	0x0100  
-  
-#define SEG_COMMAND_REG		0x17  
-/* Values for the command register */  
-#define RESET_SEG 0x0055  
-#define RESET_SEG_STATE	0x00aa  
-#define RESET_TX_CELL_CTR 0x00cc  
-  
-#define CBR_PTR_BASE	0x20  
-#define ABR_SBPTR_BASE	0x22  
-#define UBR_SBPTR_BASE  0x23  
-#define ABRWQ_BASE	0x26  
-#define UBRWQ_BASE	0x27  
-#define VCT_BASE	0x28  
-#define VCTE_BASE	0x29  
-#define CBR_TAB_BEG	0x2c  
-#define CBR_TAB_END	0x2d  
-#define PRQ_ST_ADR	0x30  
-#define PRQ_ED_ADR	0x31  
-#define PRQ_RD_PTR	0x32  
-#define PRQ_WR_PTR	0x33  
-#define TCQ_ST_ADR	0x34  
-#define TCQ_ED_ADR 	0x35  
-#define TCQ_RD_PTR	0x36  
-#define TCQ_WR_PTR	0x37  
-#define SEG_QUEUE_BASE	0x40  
-#define SEG_DESC_BASE	0x41  
-#define MODE_REG_0	0x45  
-#define T_ONLINE	0x0002		/* (i)chipSAR is online */  
-  
-#define MODE_REG_1	0x46  
-#define MODE_REG_1_VAL	0x0400		/*for propoer device operation*/  
-  
-#define SEG_INTR_STATUS_REG 0x47  
-#define SEG_MASK_REG	0x48  
-#define TRANSMIT_DONE 0x0200
-#define TCQ_NOT_EMPTY 0x1000	/* this can be used for both the interrupt   
-				status registers as well as the mask register */  
-  
-#define CELL_CTR_HIGH_AUTO 0x49  
-#define CELL_CTR_HIGH_NOAUTO 0xc9  
-#define CELL_CTR_LO_AUTO 0x4a  
-#define CELL_CTR_LO_NOAUTO 0xca  
-  
-/* Diagnostic registers */  
-#define NEXTDESC 	0x59  
-#define NEXTVC		0x5a  
-#define PSLOTCNT	0x5d  
-#define NEWDN		0x6a  
-#define NEWVC		0x6b  
-#define SBPTR		0x6c  
-#define ABRWQ_WRPTR	0x6f  
-#define ABRWQ_RDPTR	0x70  
-#define UBRWQ_WRPTR	0x71  
-#define UBRWQ_RDPTR	0x72  
-#define CBR_VC		0x73  
-#define ABR_SBVC	0x75  
-#define UBR_SBVC	0x76  
-#define ABRNEXTLINK	0x78  
-#define UBRNEXTLINK	0x79  
-  
-  
-/*----------------- Reassembly control registers ---------------------*/  
-/* The reassembly registers are 16 bits access and the addresses  
-	are defined as such so the addresses are the actual "offsets" */  
-#define MODE_REG	0x00  
-#define R_ONLINE	0x0002		/* (i)chip is online */  
-#define IGN_RAW_FL     	0x0004
-  
-#define PROTOCOL_ID	0x01  
-#define REASS_MASK_REG	0x02  
-#define REASS_INTR_STATUS_REG	0x03  
-/* Interrupt Status register bits */  
-#define RX_PKT_CTR_OF	0x8000  
-#define RX_ERR_CTR_OF	0x4000  
-#define RX_CELL_CTR_OF	0x1000  
-#define RX_FREEQ_EMPT	0x0200  
-#define RX_EXCPQ_FL	0x0080  
-#define	RX_RAWQ_FL	0x0010  
-#define RX_EXCP_RCVD	0x0008  
-#define RX_PKT_RCVD	0x0004  
-#define RX_RAW_RCVD	0x0001  
-  
-#define DRP_PKT_CNTR	0x04  
-#define ERR_CNTR	0x05  
-#define RAW_BASE_ADR	0x08  
-#define CELL_CTR0	0x0c  
-#define CELL_CTR1	0x0d  
-#define REASS_COMMAND_REG	0x0f  
-/* Values for command register */  
-#define RESET_REASS	0x0055  
-#define RESET_REASS_STATE 0x00aa  
-#define RESET_DRP_PKT_CNTR 0x00f1  
-#define RESET_ERR_CNTR	0x00f2  
-#define RESET_CELL_CNTR 0x00f8  
-#define RESET_REASS_ALL_REGS 0x00ff  
-  
-#define REASS_DESC_BASE	0x10  
-#define VC_LKUP_BASE	0x11  
-#define REASS_TABLE_BASE 0x12  
-#define REASS_QUEUE_BASE 0x13  
-#define PKT_TM_CNT	0x16  
-#define TMOUT_RANGE	0x17  
-#define INTRVL_CNTR	0x18  
-#define TMOUT_INDX	0x19  
-#define VP_LKUP_BASE	0x1c  
-#define VP_FILTER	0x1d  
-#define ABR_LKUP_BASE	0x1e  
-#define FREEQ_ST_ADR	0x24  
-#define FREEQ_ED_ADR	0x25  
-#define FREEQ_RD_PTR	0x26  
-#define FREEQ_WR_PTR	0x27  
-#define PCQ_ST_ADR	0x28  
-#define PCQ_ED_ADR	0x29  
-#define PCQ_RD_PTR	0x2a  
-#define PCQ_WR_PTR	0x2b  
-#define EXCP_Q_ST_ADR	0x2c  
-#define EXCP_Q_ED_ADR	0x2d  
-#define EXCP_Q_RD_PTR	0x2e  
-#define EXCP_Q_WR_PTR	0x2f  
-#define CC_FIFO_ST_ADR	0x34  
-#define CC_FIFO_ED_ADR	0x35  
-#define CC_FIFO_RD_PTR	0x36  
-#define CC_FIFO_WR_PTR	0x37  
-#define STATE_REG	0x38  
-#define BUF_SIZE	0x42  
-#define XTRA_RM_OFFSET	0x44  
-#define DRP_PKT_CNTR_NC	0x84  
-#define ERR_CNTR_NC	0x85  
-#define CELL_CNTR0_NC	0x8c  
-#define CELL_CNTR1_NC	0x8d  
-  
-/* State Register bits */  
-#define EXCPQ_EMPTY	0x0040  
-#define PCQ_EMPTY	0x0010  
-#define FREEQ_EMPTY	0x0004  
-  
-  
-/*----------------- Front End registers/ DMA control --------------*/  
-/* There is a lot of documentation error regarding these offsets ???   
-	eg:- 2 offsets given 800, a00 for rx counter  
-	similarly many others  
-   Remember again that the offsets are to be 4*register number, so  
-	correct the #defines here   
-*/  
-#define IPHASE5575_TX_COUNTER		0x200	/* offset - 0x800 */  
-#define IPHASE5575_RX_COUNTER		0x280	/* offset - 0xa00 */  
-#define IPHASE5575_TX_LIST_ADDR		0x300	/* offset - 0xc00 */  
-#define IPHASE5575_RX_LIST_ADDR		0x380	/* offset - 0xe00 */  
-  
-/*--------------------------- RAM ---------------------------*/  
-/* These memory maps are actually offsets from the segmentation and reassembly  RAM base addresses */  
-  
-/* Segmentation Control Memory map */  
-#define TX_DESC_BASE	0x0000	/* Buffer Decriptor Table */  
-#define TX_COMP_Q	0x1000	/* Transmit Complete Queue */  
-#define PKT_RDY_Q	0x1400	/* Packet Ready Queue */  
-#define CBR_SCHED_TABLE	0x1800	/* CBR Table */  
-#define UBR_SCHED_TABLE	0x3000	/* UBR Table */  
-#define UBR_WAIT_Q	0x4000	/* UBR Wait Queue */  
-#define ABR_SCHED_TABLE	0x5000	/* ABR Table */  
-#define ABR_WAIT_Q	0x5800	/* ABR Wait Queue */  
-#define EXT_VC_TABLE	0x6000	/* Extended VC Table */  
-#define MAIN_VC_TABLE	0x8000	/* Main VC Table */  
-#define SCHEDSZ		1024	/* ABR and UBR Scheduling Table size */  
-#define TX_DESC_TABLE_SZ 128	/* Number of entries in the Transmit   
-					Buffer Descriptor Table */  
-  
-/* These are used as table offsets in Descriptor Table address generation */  
-#define DESC_MODE	0x0  
-#define VC_INDEX	0x1  
-#define BYTE_CNT	0x3  
-#define PKT_START_HI	0x4  
-#define PKT_START_LO	0x5  
-  
-/* Descriptor Mode Word Bits */  
-#define EOM_EN	0x0800  
-#define AAL5	0x0100  
-#define APP_CRC32 0x0400  
-#define CMPL_INT  0x1000
-  
-#define TABLE_ADDRESS(db, dn, to) \
-	(((unsigned long)(db & 0x04)) << 16) | (dn << 5) | (to << 1)  
-  
-/* Reassembly Control Memory Map */  
-#define RX_DESC_BASE	0x0000	/* Buffer Descriptor Table */  
-#define VP_TABLE	0x5c00	/* VP Table */  
-#define EXCEPTION_Q	0x5e00	/* Exception Queue */  
-#define FREE_BUF_DESC_Q	0x6000	/* Free Buffer Descriptor Queue */  
-#define PKT_COMP_Q	0x6800	/* Packet Complete Queue */  
-#define REASS_TABLE	0x7000	/* Reassembly Table */  
-#define RX_VC_TABLE	0x7800	/* VC Table */  
-#define ABR_VC_TABLE	0x8000	/* ABR VC Table */  
-#define RX_DESC_TABLE_SZ 736	/* Number of entries in the Receive   
-					Buffer Descriptor Table */  
-#define VP_TABLE_SZ	256	 /* Number of entries in VPTable */   
-#define RX_VC_TABLE_SZ 	1024	/* Number of entries in VC Table */   
-#define REASS_TABLE_SZ 	1024	/* Number of entries in Reassembly Table */  
- /* Buffer Descriptor Table */  
-#define RX_ACT	0x8000  
-#define RX_VPVC	0x4000  
-#define RX_CNG	0x0040  
-#define RX_CER	0x0008  
-#define RX_PTE	0x0004  
-#define RX_OFL	0x0002  
-#define NUM_RX_EXCP   32
-
-/* Reassembly Table */  
-#define NO_AAL5_PKT	0x0000  
-#define AAL5_PKT_REASSEMBLED 0x4000  
-#define AAL5_PKT_TERMINATED 0x8000  
-#define RAW_PKT		0xc000  
-#define REASS_ABR	0x2000  
-  
-/*-------------------- Base Registers --------------------*/  
-#define REG_BASE IPHASE5575_BUS_CONTROL_REG_BASE  
-#define RAM_BASE IPHASE5575_FRAG_CONTROL_RAM_BASE  
-#define PHY_BASE IPHASE5575_FRONT_END_REG_BASE  
-#define SEG_BASE IPHASE5575_FRAG_CONTROL_REG_BASE  
-#define REASS_BASE IPHASE5575_REASS_CONTROL_REG_BASE  
-
-typedef volatile u_int	ffreg_t;
-typedef u_int   rreg_t;
-
-typedef struct _ffredn_t {
-	ffreg_t	idlehead_high;	/* Idle cell header (high)		*/
-	ffreg_t	idlehead_low;	/* Idle cell header (low)		*/
-	ffreg_t	maxrate;	/* Maximum rate				*/
-	ffreg_t	stparms;	/* Traffic Management Parameters	*/
-	ffreg_t	abrubr_abr;	/* ABRUBR Priority Byte 1, TCR Byte 0	*/
-	ffreg_t	rm_type;	/*					*/
-	u_int	filler5[0x17 - 0x06];
-	ffreg_t	cmd_reg;	/* Command register			*/
-	u_int	filler18[0x20 - 0x18];
-	ffreg_t	cbr_base;	/* CBR Pointer Base			*/
-	ffreg_t	vbr_base;	/* VBR Pointer Base			*/
-	ffreg_t	abr_base;	/* ABR Pointer Base			*/
-	ffreg_t	ubr_base;	/* UBR Pointer Base			*/
-	u_int	filler24;
-	ffreg_t	vbrwq_base;	/* VBR Wait Queue Base			*/
-	ffreg_t	abrwq_base;	/* ABR Wait Queue Base			*/
-	ffreg_t	ubrwq_base;	/* UBR Wait Queue Base			*/
-	ffreg_t	vct_base;	/* Main VC Table Base			*/
-	ffreg_t	vcte_base;	/* Extended Main VC Table Base		*/
-	u_int	filler2a[0x2C - 0x2A];
-	ffreg_t	cbr_tab_beg;	/* CBR Table Begin			*/
-	ffreg_t	cbr_tab_end;	/* CBR Table End			*/
-	ffreg_t	cbr_pointer;	/* CBR Pointer				*/
-	u_int	filler2f[0x30 - 0x2F];
-	ffreg_t	prq_st_adr;	/* Packet Ready Queue Start Address	*/
-	ffreg_t	prq_ed_adr;	/* Packet Ready Queue End Address	*/
-	ffreg_t	prq_rd_ptr;	/* Packet Ready Queue read pointer	*/
-	ffreg_t	prq_wr_ptr;	/* Packet Ready Queue write pointer	*/
-	ffreg_t	tcq_st_adr;	/* Transmit Complete Queue Start Address*/
-	ffreg_t	tcq_ed_adr;	/* Transmit Complete Queue End Address	*/
-	ffreg_t	tcq_rd_ptr;	/* Transmit Complete Queue read pointer */
-	ffreg_t	tcq_wr_ptr;	/* Transmit Complete Queue write pointer*/
-	u_int	filler38[0x40 - 0x38];
-	ffreg_t	queue_base;	/* Base address for PRQ and TCQ		*/
-	ffreg_t	desc_base;	/* Base address of descriptor table	*/
-	u_int	filler42[0x45 - 0x42];
-	ffreg_t	mode_reg_0;	/* Mode register 0			*/
-	ffreg_t	mode_reg_1;	/* Mode register 1			*/
-	ffreg_t	intr_status_reg;/* Interrupt Status register		*/
-	ffreg_t	mask_reg;	/* Mask Register			*/
-	ffreg_t	cell_ctr_high1; /* Total cell transfer count (high)	*/
-	ffreg_t	cell_ctr_lo1;	/* Total cell transfer count (low)	*/
-	ffreg_t	state_reg;	/* Status register			*/
-	u_int	filler4c[0x58 - 0x4c];
-	ffreg_t	curr_desc_num;	/* Contains the current descriptor num	*/
-	ffreg_t	next_desc;	/* Next descriptor			*/
-	ffreg_t	next_vc;	/* Next VC				*/
-	u_int	filler5b[0x5d - 0x5b];
-	ffreg_t	present_slot_cnt;/* Present slot count			*/
-	u_int	filler5e[0x6a - 0x5e];
-	ffreg_t	new_desc_num;	/* New descriptor number		*/
-	ffreg_t	new_vc;		/* New VC				*/
-	ffreg_t	sched_tbl_ptr;	/* Schedule table pointer		*/
-	ffreg_t	vbrwq_wptr;	/* VBR wait queue write pointer		*/
-	ffreg_t	vbrwq_rptr;	/* VBR wait queue read pointer		*/
-	ffreg_t	abrwq_wptr;	/* ABR wait queue write pointer		*/
-	ffreg_t	abrwq_rptr;	/* ABR wait queue read pointer		*/
-	ffreg_t	ubrwq_wptr;	/* UBR wait queue write pointer		*/
-	ffreg_t	ubrwq_rptr;	/* UBR wait queue read pointer		*/
-	ffreg_t	cbr_vc;		/* CBR VC				*/
-	ffreg_t	vbr_sb_vc;	/* VBR SB VC				*/
-	ffreg_t	abr_sb_vc;	/* ABR SB VC				*/
-	ffreg_t	ubr_sb_vc;	/* UBR SB VC				*/
-	ffreg_t	vbr_next_link;	/* VBR next link			*/
-	ffreg_t	abr_next_link;	/* ABR next link			*/
-	ffreg_t	ubr_next_link;	/* UBR next link			*/
-	u_int	filler7a[0x7c-0x7a];
-	ffreg_t	out_rate_head;	/* Out of rate head			*/
-	u_int	filler7d[0xca-0x7d]; /* pad out to full address space	*/
-	ffreg_t	cell_ctr_high1_nc;/* Total cell transfer count (high)	*/
-	ffreg_t	cell_ctr_lo1_nc;/* Total cell transfer count (low)	*/
-	u_int	fillercc[0x100-0xcc]; /* pad out to full address space	 */
-} ffredn_t;
-
-typedef struct _rfredn_t {
-        rreg_t  mode_reg_0;     /* Mode register 0                      */
-        rreg_t  protocol_id;    /* Protocol ID                          */
-        rreg_t  mask_reg;       /* Mask Register                        */
-        rreg_t  intr_status_reg;/* Interrupt status register            */
-        rreg_t  drp_pkt_cntr;   /* Dropped packet cntr (clear on read)  */
-        rreg_t  err_cntr;       /* Error Counter (cleared on read)      */
-        u_int   filler6[0x08 - 0x06];
-        rreg_t  raw_base_adr;   /* Base addr for raw cell Q             */
-        u_int   filler2[0x0c - 0x09];
-        rreg_t  cell_ctr0;      /* Cell Counter 0 (cleared when read)   */
-        rreg_t  cell_ctr1;      /* Cell Counter 1 (cleared when read)   */
-        u_int   filler3[0x0f - 0x0e];
-        rreg_t  cmd_reg;        /* Command register                     */
-        rreg_t  desc_base;      /* Base address for description table   */
-        rreg_t  vc_lkup_base;   /* Base address for VC lookup table     */
-        rreg_t  reass_base;     /* Base address for reassembler table   */
-        rreg_t  queue_base;     /* Base address for Communication queue */
-        u_int   filler14[0x16 - 0x14];
-        rreg_t  pkt_tm_cnt;     /* Packet Timeout and count register    */
-        rreg_t  tmout_range;    /* Range of reassembley IDs for timeout */
-        rreg_t  intrvl_cntr;    /* Packet aging interval counter        */
-        rreg_t  tmout_indx;     /* index of pkt being tested for aging  */
-        u_int   filler1a[0x1c - 0x1a];
-        rreg_t  vp_lkup_base;   /* Base address for VP lookup table     */
-        rreg_t  vp_filter;      /* VP filter register                   */
-        rreg_t  abr_lkup_base;  /* Base address of ABR VC Table         */
-        u_int   filler1f[0x24 - 0x1f];
-        rreg_t  fdq_st_adr;     /* Free desc queue start address        */
-        rreg_t  fdq_ed_adr;     /* Free desc queue end address          */
-        rreg_t  fdq_rd_ptr;     /* Free desc queue read pointer         */
-        rreg_t  fdq_wr_ptr;     /* Free desc queue write pointer        */
-        rreg_t  pcq_st_adr;     /* Packet Complete queue start address  */
-        rreg_t  pcq_ed_adr;     /* Packet Complete queue end address    */
-        rreg_t  pcq_rd_ptr;     /* Packet Complete queue read pointer   */
-        rreg_t  pcq_wr_ptr;     /* Packet Complete queue write pointer  */
-        rreg_t  excp_st_adr;    /* Exception queue start address        */
-        rreg_t  excp_ed_adr;    /* Exception queue end address          */
-        rreg_t  excp_rd_ptr;    /* Exception queue read pointer         */
-        rreg_t  excp_wr_ptr;    /* Exception queue write pointer        */
-        u_int   filler30[0x34 - 0x30];
-        rreg_t  raw_st_adr;     /* Raw Cell start address               */
-        rreg_t  raw_ed_adr;     /* Raw Cell end address                 */
-        rreg_t  raw_rd_ptr;     /* Raw Cell read pointer                */
-        rreg_t  raw_wr_ptr;     /* Raw Cell write pointer               */
-        rreg_t  state_reg;      /* State Register                       */
-        u_int   filler39[0x42 - 0x39];
-        rreg_t  buf_size;       /* Buffer size                          */
-        u_int   filler43;
-        rreg_t  xtra_rm_offset; /* Offset of the additional turnaround RM */
-        u_int   filler45[0x84 - 0x45];
-        rreg_t  drp_pkt_cntr_nc;/* Dropped Packet cntr, Not clear on rd */
-        rreg_t  err_cntr_nc;    /* Error Counter, Not clear on read     */
-        u_int   filler86[0x8c - 0x86];
-        rreg_t  cell_ctr0_nc;   /* Cell Counter 0,  Not clear on read   */
-        rreg_t  cell_ctr1_nc;   /* Cell Counter 1, Not clear on read    */
-        u_int   filler8e[0x100-0x8e]; /* pad out to full address space   */
-} rfredn_t;
-
-typedef struct {
-        /* Atlantic */
-        ffredn_t        ffredn;         /* F FRED                       */
-        rfredn_t        rfredn;         /* R FRED                       */
-} ia_regs_t;
-
-typedef struct {
-	u_short		f_vc_type;	/* VC type              */
-	u_short		f_nrm;		/* Nrm			*/
-	u_short		f_nrmexp;	/* Nrm Exp              */
-	u_short		reserved6;	/* 			*/
-	u_short		f_crm;		/* Crm			*/
-	u_short		reserved10;	/* Reserved		*/
-	u_short		reserved12;	/* Reserved		*/
-	u_short		reserved14;	/* Reserved		*/
-	u_short		last_cell_slot;	/* last_cell_slot_count	*/
-	u_short		f_pcr;		/* Peak Cell Rate	*/
-	u_short		fraction;	/* fraction		*/
-	u_short		f_icr;		/* Initial Cell Rate	*/
-	u_short		f_cdf;		/* */
-	u_short		f_mcr;		/* Minimum Cell Rate	*/
-	u_short		f_acr;		/* Allowed Cell Rate	*/
-	u_short		f_status;	/* */
-} f_vc_abr_entry;
-
-typedef struct {
-        u_short         r_status_rdf;   /* status + RDF         */
-        u_short         r_air;          /* AIR                  */
-        u_short         reserved4[14];  /* Reserved             */
-} r_vc_abr_entry;   
-
-#define MRM 3
-
-typedef struct srv_cls_param {
-        u32 class_type;         /* CBR/VBR/ABR/UBR; use the enum above */
-        u32 pcr;                /* Peak Cell Rate (24-bit) */ 
-        /* VBR parameters */
-        u32 scr;                /* sustainable cell rate */
-        u32 max_burst_size;     /* ?? cell rate or data rate */
- 
-        /* ABR only UNI 4.0 Parameters */
-        u32 mcr;                /* Min Cell Rate (24-bit) */
-        u32 icr;                /* Initial Cell Rate (24-bit) */
-        u32 tbe;                /* Transient Buffer Exposure (24-bit) */
-        u32 frtt;               /* Fixed Round Trip Time (24-bit) */
- 
-#if 0   /* Additional Parameters of TM 4.0 */
-bits  31          30           29          28       27-25 24-22 21-19  18-9
------------------------------------------------------------------------------
-| NRM present | TRM prsnt | CDF prsnt | ADTF prsnt | NRM | TRM | CDF | ADTF |
------------------------------------------------------------------------------
-#endif /* 0 */
- 
-        u8 nrm;                 /* Max # of Cells for each forward RM
-                                        cell (3-bit) */
-        u8 trm;                 /* Time between forward RM cells (3-bit) */
-        u16 adtf;               /* ACR Decrease Time Factor (10-bit) */
-        u8 cdf;                 /* Cutoff Decrease Factor (3-bit) */
-        u8 rif;                 /* Rate Increment Factor (4-bit) */
-        u8 rdf;                 /* Rate Decrease Factor (4-bit) */
-        u8 reserved;            /* 8 bits to keep structure word aligned */
-} srv_cls_param_t;
-
-struct testTable_t {
-	u16 lastTime; 
-	u16 fract; 
-	u8 vc_status;
-}; 
-
-typedef struct {
-	u16 vci;
-	u16 error;
-} RX_ERROR_Q;
-
-typedef struct {
-	u8 active: 1; 
-	u8 abr: 1; 
-	u8 ubr: 1; 
-	u8 cnt: 5;
-#define VC_ACTIVE 	0x01
-#define VC_ABR		0x02
-#define VC_UBR		0x04
-} vcstatus_t;
-  
-struct ia_rfL_t {
-    	u32  fdq_st;     /* Free desc queue start address        */
-        u32  fdq_ed;     /* Free desc queue end address          */
-        u32  fdq_rd;     /* Free desc queue read pointer         */
-        u32  fdq_wr;     /* Free desc queue write pointer        */
-        u32  pcq_st;     /* Packet Complete queue start address  */
-        u32  pcq_ed;     /* Packet Complete queue end address    */
-        u32  pcq_rd;     /* Packet Complete queue read pointer   */
-        u32  pcq_wr;     /* Packet Complete queue write pointer  */ 
-};
-
-struct ia_ffL_t {
-	u32  prq_st;     /* Packet Ready Queue Start Address     */
-        u32  prq_ed;     /* Packet Ready Queue End Address       */
-        u32  prq_wr;     /* Packet Ready Queue write pointer     */
-        u32  tcq_st;     /* Transmit Complete Queue Start Address*/
-        u32  tcq_ed;     /* Transmit Complete Queue End Address  */
-        u32  tcq_rd;     /* Transmit Complete Queue read pointer */
-};
-
-struct desc_tbl_t {
-        u32 timestamp;
-        struct ia_vcc *iavcc;
-        struct sk_buff *txskb;
-}; 
-
-typedef struct ia_rtn_q {
-   struct desc_tbl_t data;
-   struct ia_rtn_q *next, *tail;
-} IARTN_Q;
-
-#define SUNI_LOSV   	0x04
-enum ia_suni {
-	SUNI_MASTER_RESET	= 0x000, /* SUNI Master Reset and Identity   */
-	SUNI_MASTER_CONFIG	= 0x004, /* SUNI Master Configuration        */
-	SUNI_MASTER_INTR_STAT	= 0x008, /* SUNI Master Interrupt Status     */
-	SUNI_RESERVED1		= 0x00c, /* Reserved                         */
-	SUNI_MASTER_CLK_MONITOR	= 0x010, /* SUNI Master Clock Monitor        */
-	SUNI_MASTER_CONTROL	= 0x014, /* SUNI Master Clock Monitor        */
-					 /* Reserved (10)                    */
-	SUNI_RSOP_CONTROL	= 0x040, /* RSOP Control/Interrupt Enable    */
-	SUNI_RSOP_STATUS	= 0x044, /* RSOP Status/Interrupt States     */
-	SUNI_RSOP_SECTION_BIP8L	= 0x048, /* RSOP Section BIP-8 LSB           */
-	SUNI_RSOP_SECTION_BIP8M	= 0x04c, /* RSOP Section BIP-8 MSB           */
-
-	SUNI_TSOP_CONTROL	= 0x050, /* TSOP Control                     */
-	SUNI_TSOP_DIAG		= 0x054, /* TSOP Disgnostics                 */
-					 /* Reserved (2)                     */
-	SUNI_RLOP_CS		= 0x060, /* RLOP Control/Status              */
-	SUNI_RLOP_INTR		= 0x064, /* RLOP Interrupt Enable/Status     */
-	SUNI_RLOP_LINE_BIP24L	= 0x068, /* RLOP Line BIP-24 LSB             */
-	SUNI_RLOP_LINE_BIP24	= 0x06c, /* RLOP Line BIP-24                 */
-	SUNI_RLOP_LINE_BIP24M	= 0x070, /* RLOP Line BIP-24 MSB             */
-	SUNI_RLOP_LINE_FEBEL	= 0x074, /* RLOP Line FEBE LSB               */
-	SUNI_RLOP_LINE_FEBE	= 0x078, /* RLOP Line FEBE                   */
-	SUNI_RLOP_LINE_FEBEM	= 0x07c, /* RLOP Line FEBE MSB               */
-
-	SUNI_TLOP_CONTROL	= 0x080, /* TLOP Control                     */
-	SUNI_TLOP_DISG		= 0x084, /* TLOP Disgnostics                 */
-					 /* Reserved (14)                    */
-	SUNI_RPOP_CS		= 0x0c0, /* RPOP Status/Control              */
-	SUNI_RPOP_INTR		= 0x0c4, /* RPOP Interrupt/Status            */
-	SUNI_RPOP_RESERVED	= 0x0c8, /* RPOP Reserved                    */
-	SUNI_RPOP_INTR_ENA	= 0x0cc, /* RPOP Interrupt Enable            */
-					 /* Reserved (3)                     */
-	SUNI_RPOP_PATH_SIG	= 0x0dc, /* RPOP Path Signal Label           */
-	SUNI_RPOP_BIP8L		= 0x0e0, /* RPOP Path BIP-8 LSB              */
-	SUNI_RPOP_BIP8M		= 0x0e4, /* RPOP Path BIP-8 MSB              */
-	SUNI_RPOP_FEBEL		= 0x0e8, /* RPOP Path FEBE LSB               */
-	SUNI_RPOP_FEBEM		= 0x0ec, /* RPOP Path FEBE MSB               */
-					 /* Reserved (4)                     */
-	SUNI_TPOP_CNTRL_DAIG	= 0x100, /* TPOP Control/Disgnostics         */
-	SUNI_TPOP_POINTER_CTRL	= 0x104, /* TPOP Pointer Control             */
-	SUNI_TPOP_SOURCER_CTRL	= 0x108, /* TPOP Source Control              */
-					 /* Reserved (2)                     */
-	SUNI_TPOP_ARB_PRTL	= 0x114, /* TPOP Arbitrary Pointer LSB       */
-	SUNI_TPOP_ARB_PRTM	= 0x118, /* TPOP Arbitrary Pointer MSB       */
-	SUNI_TPOP_RESERVED2	= 0x11c, /* TPOP Reserved                    */
-	SUNI_TPOP_PATH_SIG	= 0x120, /* TPOP Path Signal Lable           */
-	SUNI_TPOP_PATH_STATUS	= 0x124, /* TPOP Path Status                 */
-					 /* Reserved (6)                     */
-	SUNI_RACP_CS		= 0x140, /* RACP Control/Status              */
-	SUNI_RACP_INTR		= 0x144, /* RACP Interrupt Enable/Status     */
-	SUNI_RACP_HDR_PATTERN	= 0x148, /* RACP Match Header Pattern        */
-	SUNI_RACP_HDR_MASK	= 0x14c, /* RACP Match Header Mask           */
-	SUNI_RACP_CORR_HCS	= 0x150, /* RACP Correctable HCS Error Count */
-	SUNI_RACP_UNCORR_HCS	= 0x154, /* RACP Uncorrectable HCS Err Count */
-					 /* Reserved (10)                    */
-	SUNI_TACP_CONTROL	= 0x180, /* TACP Control                     */
-	SUNI_TACP_IDLE_HDR_PAT	= 0x184, /* TACP Idle Cell Header Pattern    */
-	SUNI_TACP_IDLE_PAY_PAY	= 0x188, /* TACP Idle Cell Payld Octet Patrn */
-					 /* Reserved (5)                     */
-					 /* Reserved (24)                    */
-	/* FIXME: unused but name conflicts.
-	 * SUNI_MASTER_TEST	= 0x200,    SUNI Master Test                 */
-	SUNI_RESERVED_TEST	= 0x204  /* SUNI Reserved for Test           */
-};
-
-typedef struct _SUNI_STATS_
-{
-   u32 valid;                       // 1 = oc3 PHY card
-   u32 carrier_detect;              // GPIN input
-   // RSOP: receive section overhead processor
-   u16 rsop_oof_state;              // 1 = out of frame
-   u16 rsop_lof_state;              // 1 = loss of frame
-   u16 rsop_los_state;              // 1 = loss of signal
-   u32 rsop_los_count;              // loss of signal count
-   u32 rsop_bse_count;              // section BIP-8 error count
-   // RLOP: receive line overhead processor
-   u16 rlop_ferf_state;             // 1 = far end receive failure
-   u16 rlop_lais_state;             // 1 = line AIS
-   u32 rlop_lbe_count;              // BIP-24 count
-   u32 rlop_febe_count;             // FEBE count;
-   // RPOP: receive path overhead processor
-   u16 rpop_lop_state;              // 1 = LOP
-   u16 rpop_pais_state;             // 1 = path AIS
-   u16 rpop_pyel_state;             // 1 = path yellow alert
-   u32 rpop_bip_count;              // path BIP-8 error count
-   u32 rpop_febe_count;             // path FEBE error count
-   u16 rpop_psig;                   // path signal label value
-   // RACP: receive ATM cell processor
-   u16 racp_hp_state;               // hunt/presync state
-   u32 racp_fu_count;               // FIFO underrun count
-   u32 racp_fo_count;               // FIFO overrun count
-   u32 racp_chcs_count;             // correctable HCS error count
-   u32 racp_uchcs_count;            // uncorrectable HCS error count
-} IA_SUNI_STATS; 
-
-typedef struct iadev_priv {
-	/*-----base pointers into (i)chipSAR+ address space */   
-	u32 __iomem *phy;	/* Base pointer into phy (SUNI). */
-	u32 __iomem *dma;	/* Base pointer into DMA control registers. */
-	u32 __iomem *reg;	/* Base pointer to SAR registers. */
-	u32 __iomem *seg_reg;		/* base pointer to segmentation engine  
-						internal registers */  
-	u32 __iomem *reass_reg;		/* base pointer to reassemble engine  
-						internal registers */  
-	u32 __iomem *ram;		/* base pointer to SAR RAM */  
-	void __iomem *seg_ram;  
-	void __iomem *reass_ram;  
-	struct dle_q tx_dle_q;  
-	struct free_desc_q *tx_free_desc_qhead;  
-	struct sk_buff_head tx_dma_q, tx_backlog;  
-        spinlock_t            tx_lock;
-        IARTN_Q               tx_return_q;
-        u32                   close_pending;
-        wait_queue_head_t    close_wait;
-        wait_queue_head_t    timeout_wait;
-	struct cpcs_trailer_desc *tx_buf;
-        u16 num_tx_desc, tx_buf_sz, rate_limit;
-        u32 tx_cell_cnt, tx_pkt_cnt;
-        void __iomem *MAIN_VC_TABLE_ADDR, *EXT_VC_TABLE_ADDR, *ABR_SCHED_TABLE_ADDR;
-	struct dle_q rx_dle_q;  
-	struct free_desc_q *rx_free_desc_qhead;  
-	struct sk_buff_head rx_dma_q;  
-	spinlock_t rx_lock;
-	struct atm_vcc **rx_open;	/* list of all open VCs */  
-        u16 num_rx_desc, rx_buf_sz, rxing;
-        u32 rx_pkt_ram, rx_tmp_cnt;
-        unsigned long rx_tmp_jif;
-        void __iomem *RX_DESC_BASE_ADDR;
-        u32 drop_rxpkt, drop_rxcell, rx_cell_cnt, rx_pkt_cnt;
-	struct atm_dev *next_board;	/* other iphase devices */  
-	struct pci_dev *pci;  
-	int mem;  
-	unsigned int real_base;	/* real and virtual base address */  
-	void __iomem *base;
-	unsigned int pci_map_size;	/*pci map size of board */  
-	unsigned char irq;  
-	unsigned char bus;  
-	unsigned char dev_fn;  
-        u_short  phy_type;
-        u_short  num_vc, memSize, memType;
-        struct ia_ffL_t ffL;
-        struct ia_rfL_t rfL;
-        /* Suni stat */
-        // IA_SUNI_STATS suni_stats;
-        unsigned char carrier_detect;
-        /* CBR related */
-        // transmit DMA & Receive
-        unsigned int tx_dma_cnt;     // number of elements on dma queue
-        unsigned int rx_dma_cnt;     // number of elements on rx dma queue
-        unsigned int NumEnabledCBR;  // number of CBR VCI's enabled.     CBR
-        // receive MARK  for Cell FIFO
-        unsigned int rx_mark_cnt;    // number of elements on mark queue
-        unsigned int CbrTotEntries;  // Total CBR Entries in Scheduling Table.
-        unsigned int CbrRemEntries;  // Remaining CBR Entries in Scheduling Table.
-        unsigned int CbrEntryPt;     // CBR Sched Table Entry Point.
-        unsigned int Granularity;    // CBR Granularity given Table Size.
-        /* ABR related */
-	unsigned int  sum_mcr, sum_cbr, LineRate;
-	unsigned int  n_abr;
-        struct desc_tbl_t *desc_tbl;
-        u_short host_tcq_wr;
-        struct testTable_t **testTable;
-	dma_addr_t tx_dle_dma;
-	dma_addr_t rx_dle_dma;
-} IADEV;
-  
-  
-#define INPH_IA_DEV(d) ((IADEV *) (d)->dev_data)  
-#define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data)  
-
-/******************* IDT77105 25MB/s PHY DEFINE *****************************/
-enum ia_mb25 {
-	MB25_MASTER_CTRL	= 0x00, /* Master control		     */
-	MB25_INTR_STATUS	= 0x04,	/* Interrupt status		     */
-	MB25_DIAG_CONTROL	= 0x08,	/* Diagnostic control		     */
-	MB25_LED_HEC		= 0x0c,	/* LED driver and HEC status/control */
-	MB25_LOW_BYTE_COUNTER	= 0x10,
-	MB25_HIGH_BYTE_COUNTER	= 0x14
-};
-
-/*
- * Master Control
- */
-#define	MB25_MC_UPLO	0x80		/* UPLO				     */
-#define	MB25_MC_DREC	0x40		/* Discard receive cell errors	     */
-#define	MB25_MC_ECEIO	0x20		/* Enable Cell Error Interrupts Only */
-#define	MB25_MC_TDPC	0x10		/* Transmit data parity check	     */
-#define	MB25_MC_DRIC	0x08		/* Discard receive idle cells	     */
-#define	MB25_MC_HALTTX	0x04		/* Halt Tx			     */
-#define	MB25_MC_UMS	0x02		/* UTOPIA mode select		     */
-#define	MB25_MC_ENABLED	0x01		/* Enable interrupt		     */
-
-/*
- * Interrupt Status
- */
-#define	MB25_IS_GSB	0x40		/* GOOD Symbol Bit		     */	
-#define	MB25_IS_HECECR	0x20		/* HEC error cell received	     */
-#define	MB25_IS_SCR	0x10		/* "Short Cell" Received	     */
-#define	MB25_IS_TPE	0x08		/* Trnamsit Parity Error	     */
-#define	MB25_IS_RSCC	0x04		/* Receive Signal Condition change   */
-#define	MB25_IS_RCSE	0x02		/* Received Cell Symbol Error	     */
-#define	MB25_IS_RFIFOO	0x01		/* Received FIFO Overrun	     */
-
-/*
- * Diagnostic Control
- */
-#define	MB25_DC_FTXCD	0x80		/* Force TxClav deassert	     */	
-#define	MB25_DC_RXCOS	0x40		/* RxClav operation select	     */
-#define	MB25_DC_ECEIO	0x20		/* Single/Multi-PHY config select    */
-#define	MB25_DC_RLFLUSH	0x10		/* Clear receive FIFO		     */
-#define	MB25_DC_IXPE	0x08		/* Insert xmit payload error	     */
-#define	MB25_DC_IXHECE	0x04		/* Insert Xmit HEC Error	     */
-#define	MB25_DC_LB_MASK	0x03		/* Loopback control mask	     */
-
-#define	MB25_DC_LL	0x03		/* Line Loopback		     */
-#define	MB25_DC_PL	0x02		/* PHY Loopback			     */
-#define	MB25_DC_NM	0x00		
-
-#define FE_MASK 	0x00F0
-#define FE_MULTI_MODE	0x0000
-#define FE_SINGLE_MODE  0x0010 
-#define FE_UTP_OPTION  	0x0020
-#define FE_25MBIT_PHY	0x0040
-#define FE_DS3_PHY      0x0080          /* DS3 */
-#define FE_E3_PHY       0x0090          /* E3 */
-		     
-/*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
-enum suni_pm7345 {
-	SUNI_CONFIG			= 0x000, /* SUNI Configuration */
-	SUNI_INTR_ENBL			= 0x004, /* SUNI Interrupt Enable */
-	SUNI_INTR_STAT			= 0x008, /* SUNI Interrupt Status */
-	SUNI_CONTROL			= 0x00c, /* SUNI Control */
-	SUNI_ID_RESET			= 0x010, /* SUNI Reset and Identity */
-	SUNI_DATA_LINK_CTRL		= 0x014,
-	SUNI_RBOC_CONF_INTR_ENBL	= 0x018,
-	SUNI_RBOC_STAT			= 0x01c,
-	SUNI_DS3_FRM_CFG		= 0x020,
-	SUNI_DS3_FRM_INTR_ENBL		= 0x024,
-	SUNI_DS3_FRM_INTR_STAT		= 0x028,
-	SUNI_DS3_FRM_STAT		= 0x02c,
-	SUNI_RFDL_CFG			= 0x030,
-	SUNI_RFDL_ENBL_STAT		= 0x034,
-	SUNI_RFDL_STAT			= 0x038,
-	SUNI_RFDL_DATA			= 0x03c,
-	SUNI_PMON_CHNG			= 0x040,
-	SUNI_PMON_INTR_ENBL_STAT	= 0x044,
-	/* SUNI_RESERVED1 (0x13 - 0x11) */
-	SUNI_PMON_LCV_EVT_CNT_LSB	= 0x050,
-	SUNI_PMON_LCV_EVT_CNT_MSB	= 0x054,
-	SUNI_PMON_FBE_EVT_CNT_LSB	= 0x058,
-	SUNI_PMON_FBE_EVT_CNT_MSB	= 0x05c,
-	SUNI_PMON_SEZ_DET_CNT_LSB	= 0x060,
-	SUNI_PMON_SEZ_DET_CNT_MSB	= 0x064,
-	SUNI_PMON_PE_EVT_CNT_LSB	= 0x068,
-	SUNI_PMON_PE_EVT_CNT_MSB	= 0x06c,
-	SUNI_PMON_PPE_EVT_CNT_LSB	= 0x070,
-	SUNI_PMON_PPE_EVT_CNT_MSB	= 0x074,
-	SUNI_PMON_FEBE_EVT_CNT_LSB	= 0x078,
-	SUNI_PMON_FEBE_EVT_CNT_MSB	= 0x07c,
-	SUNI_DS3_TRAN_CFG		= 0x080,
-	SUNI_DS3_TRAN_DIAG		= 0x084,
-	/* SUNI_RESERVED2 (0x23 - 0x21) */
-	SUNI_XFDL_CFG			= 0x090,
-	SUNI_XFDL_INTR_ST		= 0x094,
-	SUNI_XFDL_XMIT_DATA		= 0x098,
-	SUNI_XBOC_CODE			= 0x09c,
-	SUNI_SPLR_CFG			= 0x0a0,
-	SUNI_SPLR_INTR_EN		= 0x0a4,
-	SUNI_SPLR_INTR_ST		= 0x0a8,
-	SUNI_SPLR_STATUS		= 0x0ac,
-	SUNI_SPLT_CFG			= 0x0b0,
-	SUNI_SPLT_CNTL			= 0x0b4,
-	SUNI_SPLT_DIAG_G1		= 0x0b8,
-	SUNI_SPLT_F1			= 0x0bc,
-	SUNI_CPPM_LOC_METERS		= 0x0c0,
-	SUNI_CPPM_CHG_OF_CPPM_PERF_METR	= 0x0c4,
-	SUNI_CPPM_B1_ERR_CNT_LSB	= 0x0c8,
-	SUNI_CPPM_B1_ERR_CNT_MSB	= 0x0cc,
-	SUNI_CPPM_FRAMING_ERR_CNT_LSB	= 0x0d0,
-	SUNI_CPPM_FRAMING_ERR_CNT_MSB	= 0x0d4,
-	SUNI_CPPM_FEBE_CNT_LSB		= 0x0d8,
-	SUNI_CPPM_FEBE_CNT_MSB		= 0x0dc,
-	SUNI_CPPM_HCS_ERR_CNT_LSB	= 0x0e0,
-	SUNI_CPPM_HCS_ERR_CNT_MSB	= 0x0e4,
-	SUNI_CPPM_IDLE_UN_CELL_CNT_LSB	= 0x0e8,
-	SUNI_CPPM_IDLE_UN_CELL_CNT_MSB	= 0x0ec,
-	SUNI_CPPM_RCV_CELL_CNT_LSB	= 0x0f0,
-	SUNI_CPPM_RCV_CELL_CNT_MSB	= 0x0f4,
-	SUNI_CPPM_XMIT_CELL_CNT_LSB	= 0x0f8,
-	SUNI_CPPM_XMIT_CELL_CNT_MSB	= 0x0fc,
-	SUNI_RXCP_CTRL			= 0x100,
-	SUNI_RXCP_FCTRL			= 0x104,
-	SUNI_RXCP_INTR_EN_STS		= 0x108,
-	SUNI_RXCP_IDLE_PAT_H1		= 0x10c,
-	SUNI_RXCP_IDLE_PAT_H2		= 0x110,
-	SUNI_RXCP_IDLE_PAT_H3		= 0x114,
-	SUNI_RXCP_IDLE_PAT_H4		= 0x118,
-	SUNI_RXCP_IDLE_MASK_H1		= 0x11c,
-	SUNI_RXCP_IDLE_MASK_H2		= 0x120,
-	SUNI_RXCP_IDLE_MASK_H3		= 0x124,
-	SUNI_RXCP_IDLE_MASK_H4		= 0x128,
-	SUNI_RXCP_CELL_PAT_H1		= 0x12c,
-	SUNI_RXCP_CELL_PAT_H2		= 0x130,
-	SUNI_RXCP_CELL_PAT_H3		= 0x134,
-	SUNI_RXCP_CELL_PAT_H4		= 0x138,
-	SUNI_RXCP_CELL_MASK_H1		= 0x13c,
-	SUNI_RXCP_CELL_MASK_H2		= 0x140,
-	SUNI_RXCP_CELL_MASK_H3		= 0x144,
-	SUNI_RXCP_CELL_MASK_H4		= 0x148,
-	SUNI_RXCP_HCS_CS		= 0x14c,
-	SUNI_RXCP_LCD_CNT_THRESHOLD	= 0x150,
-	/* SUNI_RESERVED3 (0x57 - 0x54) */
-	SUNI_TXCP_CTRL			= 0x160,
-	SUNI_TXCP_INTR_EN_STS		= 0x164,
-	SUNI_TXCP_IDLE_PAT_H1		= 0x168,
-	SUNI_TXCP_IDLE_PAT_H2		= 0x16c,
-	SUNI_TXCP_IDLE_PAT_H3		= 0x170,
-	SUNI_TXCP_IDLE_PAT_H4		= 0x174,
-	SUNI_TXCP_IDLE_PAT_H5		= 0x178,
-	SUNI_TXCP_IDLE_PAYLOAD		= 0x17c,
-	SUNI_E3_FRM_FRAM_OPTIONS	= 0x180,
-	SUNI_E3_FRM_MAINT_OPTIONS	= 0x184,
-	SUNI_E3_FRM_FRAM_INTR_ENBL	= 0x188,
-	SUNI_E3_FRM_FRAM_INTR_IND_STAT	= 0x18c,
-	SUNI_E3_FRM_MAINT_INTR_ENBL	= 0x190,
-	SUNI_E3_FRM_MAINT_INTR_IND	= 0x194,
-	SUNI_E3_FRM_MAINT_STAT		= 0x198,
-	SUNI_RESERVED4			= 0x19c,
-	SUNI_E3_TRAN_FRAM_OPTIONS	= 0x1a0,
-	SUNI_E3_TRAN_STAT_DIAG_OPTIONS	= 0x1a4,
-	SUNI_E3_TRAN_BIP_8_ERR_MASK	= 0x1a8,
-	SUNI_E3_TRAN_MAINT_ADAPT_OPTS	= 0x1ac,
-	SUNI_TTB_CTRL			= 0x1b0,
-	SUNI_TTB_TRAIL_TRACE_ID_STAT	= 0x1b4,
-	SUNI_TTB_IND_ADDR		= 0x1b8,
-	SUNI_TTB_IND_DATA		= 0x1bc,
-	SUNI_TTB_EXP_PAYLOAD_TYPE	= 0x1c0,
-	SUNI_TTB_PAYLOAD_TYPE_CTRL_STAT	= 0x1c4,
-	/* SUNI_PAD5 (0x7f - 0x71) */
-	SUNI_MASTER_TEST		= 0x200,
-	/* SUNI_PAD6 (0xff - 0x80) */
-};
-
-#define SUNI_PM7345_T suni_pm7345_t
-#define SUNI_PM7345     0x20            /* Suni chip type */
-#define SUNI_PM5346     0x30            /* Suni chip type */
-/*
- * SUNI_PM7345 Configuration
- */
-#define SUNI_PM7345_CLB         0x01    /* Cell loopback        */
-#define SUNI_PM7345_PLB         0x02    /* Payload loopback     */
-#define SUNI_PM7345_DLB         0x04    /* Diagnostic loopback  */
-#define SUNI_PM7345_LLB         0x80    /* Line loopback        */
-#define SUNI_PM7345_E3ENBL      0x40    /* E3 enable bit        */
-#define SUNI_PM7345_LOOPT       0x10    /* LOOPT enable bit     */
-#define SUNI_PM7345_FIFOBP      0x20    /* FIFO bypass          */
-#define SUNI_PM7345_FRMRBP      0x08    /* Framer bypass        */
-/*
- * DS3 FRMR Interrupt Enable
- */
-#define SUNI_DS3_COFAE  0x80            /* Enable change of frame align */
-#define SUNI_DS3_REDE   0x40            /* Enable DS3 RED state intr    */
-#define SUNI_DS3_CBITE  0x20            /* Enable Appl ID channel intr  */
-#define SUNI_DS3_FERFE  0x10            /* Enable Far End Receive Failure intr*/
-#define SUNI_DS3_IDLE   0x08            /* Enable Idle signal intr      */
-#define SUNI_DS3_AISE   0x04            /* Enable Alarm Indication signal intr*/
-#define SUNI_DS3_OOFE   0x02            /* Enable Out of frame intr     */
-#define SUNI_DS3_LOSE   0x01            /* Enable Loss of signal intr   */
- 
-/*
- * DS3 FRMR Status
- */
-#define SUNI_DS3_ACE    0x80            /* Additional Configuration Reg */
-#define SUNI_DS3_REDV   0x40            /* DS3 RED state                */
-#define SUNI_DS3_CBITV  0x20            /* Application ID channel state */
-#define SUNI_DS3_FERFV  0x10            /* Far End Receive Failure state*/
-#define SUNI_DS3_IDLV   0x08            /* Idle signal state            */
-#define SUNI_DS3_AISV   0x04            /* Alarm Indication signal state*/
-#define SUNI_DS3_OOFV   0x02            /* Out of frame state           */
-#define SUNI_DS3_LOSV   0x01            /* Loss of signal state         */
-
-/*
- * E3 FRMR Interrupt/Status
- */
-#define SUNI_E3_CZDI    0x40            /* Consecutive Zeros indicator  */
-#define SUNI_E3_LOSI    0x20            /* Loss of signal intr status   */
-#define SUNI_E3_LCVI    0x10            /* Line code violation intr     */
-#define SUNI_E3_COFAI   0x08            /* Change of frame align intr   */
-#define SUNI_E3_OOFI    0x04            /* Out of frame intr status     */
-#define SUNI_E3_LOS     0x02            /* Loss of signal state         */
-#define SUNI_E3_OOF     0x01            /* Out of frame state           */
-
-/*
- * E3 FRMR Maintenance Status
- */
-#define SUNI_E3_AISD    0x80            /* Alarm Indication signal state*/
-#define SUNI_E3_FERF_RAI        0x40    /* FERF/RAI indicator           */
-#define SUNI_E3_FEBE    0x20            /* Far End Block Error indicator*/
-
-/*
- * RXCP Control/Status
- */
-#define SUNI_DS3_HCSPASS        0x80    /* Pass cell with HEC errors    */
-#define SUNI_DS3_HCSDQDB        0x40    /* Control octets in HCS calc   */
-#define SUNI_DS3_HCSADD         0x20    /* Add coset poly               */
-#define SUNI_DS3_HCK            0x10    /* Control FIFO data path integ chk*/
-#define SUNI_DS3_BLOCK          0x08    /* Enable cell filtering        */
-#define SUNI_DS3_DSCR           0x04    /* Disable payload descrambling */
-#define SUNI_DS3_OOCDV          0x02    /* Cell delineation state       */
-#define SUNI_DS3_FIFORST        0x01    /* Cell FIFO reset              */
-
-/*
- * RXCP Interrupt Enable/Status
- */
-#define SUNI_DS3_OOCDE  0x80            /* Intr enable, change in CDS   */
-#define SUNI_DS3_HCSE   0x40            /* Intr enable, corr HCS errors */
-#define SUNI_DS3_FIFOE  0x20            /* Intr enable, unco HCS errors */
-#define SUNI_DS3_OOCDI  0x10            /* SYNC state                   */
-#define SUNI_DS3_UHCSI  0x08            /* Uncorr. HCS errors detected  */
-#define SUNI_DS3_COCAI  0x04            /* Corr. HCS errors detected    */
-#define SUNI_DS3_FOVRI  0x02            /* FIFO overrun                 */
-#define SUNI_DS3_FUDRI  0x01            /* FIFO underrun                */
-
-///////////////////SUNI_PM7345 PHY DEFINE END /////////////////////////////
-
-/* ia_eeprom define*/
-#define MEM_SIZE_MASK   0x000F          /* mask of 4 bits defining memory size*/
-#define MEM_SIZE_128K   0x0000          /* board has 128k buffer */
-#define MEM_SIZE_512K   0x0001          /* board has 512K of buffer */
-#define MEM_SIZE_1M     0x0002          /* board has 1M of buffer */
-                                        /* 0x3 to 0xF are reserved for future */
-
-#define FE_MASK         0x00F0          /* mask of 4 bits defining FE type */
-#define FE_MULTI_MODE   0x0000          /* 155 MBit multimode fiber */
-#define FE_SINGLE_MODE  0x0010          /* 155 MBit single mode laser */
-#define FE_UTP_OPTION   0x0020          /* 155 MBit UTP front end */
-
-#define	NOVRAM_SIZE	64
-#define	CMD_LEN		10
-
-/***********
- *
- *	Switches and defines for header files.
- *
- *	The following defines are used to turn on and off
- *	various options in the header files. Primarily useful
- *	for debugging.
- *
- ***********/
-
-/*
- * a list of the commands that can be sent to the NOVRAM
- */
-
-#define	EXTEND	0x100
-#define	IAWRITE	0x140
-#define	IAREAD	0x180
-#define	ERASE	0x1c0
-
-#define	EWDS	0x00
-#define	WRAL	0x10
-#define	ERAL	0x20
-#define	EWEN	0x30
-
-/*
- * these bits duplicate the hw_flip.h register settings
- * note: how the data in / out bits are defined in the flipper specification 
- */
-
-#define	NVCE	0x02
-#define	NVSK	0x01
-#define	NVDO	0x08	
-#define NVDI	0x04
-/***********************
- *
- * This define ands the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define	CFG_AND(val) { \
-		u32 t; \
-		t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		t &= (val); \
-		writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-	}
-
-/***********************
- *
- * This define ors the value and the current config register and puts
- * the result in the config register
- *
- ***********************/
-
-#define	CFG_OR(val) { \
-		u32 t; \
-		t =  readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		t |= (val); \
-		writel(t, iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-	}
-
-/***********************
- *
- * Send a command to the NOVRAM, the command is in cmd.
- *
- * clear CE and SK. Then assert CE.
- * Clock each of the command bits out in the correct order with SK
- * exit with CE still asserted
- *
- ***********************/
-
-#define	NVRAM_CMD(cmd) { \
-		int	i; \
-		u_short c = cmd; \
-		CFG_AND(~(NVCE|NVSK)); \
-		CFG_OR(NVCE); \
-		for (i=0; i<CMD_LEN; i++) { \
-			NVRAM_CLKOUT((c & (1 << (CMD_LEN - 1))) ? 1 : 0); \
-			c <<= 1; \
-		} \
-	}
-
-/***********************
- *
- * clear the CE, this must be used after each command is complete
- *
- ***********************/
-
-#define	NVRAM_CLR_CE	{CFG_AND(~NVCE)}
-
-/***********************
- *
- * clock the data bit in bitval out to the NOVRAM.  The bitval must be
- * a 1 or 0, or the clockout operation is undefined
- *
- ***********************/
-
-#define	NVRAM_CLKOUT(bitval) { \
-		CFG_AND(~NVDI); \
-		CFG_OR((bitval) ? NVDI : 0); \
-		CFG_OR(NVSK); \
-		CFG_AND( ~NVSK); \
-	}
-
-/***********************
- *
- * clock the data bit in and return a 1 or 0, depending on the value
- * that was received from the NOVRAM
- *
- ***********************/
-
-#define	NVRAM_CLKIN(value) { \
-		u32 _t; \
-		CFG_OR(NVSK); \
-		CFG_AND(~NVSK); \
-		_t = readl(iadev->reg+IPHASE5575_EEPROM_ACCESS); \
-		value = (_t & NVDO) ? 1 : 0; \
-	}
-
-
-#endif /* IPHASE_H */
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c
deleted file mode 100644
index d6af999..0000000
--- a/drivers/atm/lanai.c
+++ /dev/null
@@ -1,2603 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* lanai.c -- Copyright 1999-2003 by Mitchell Blank Jr <mitch@sfgoth.com>
- *
- * This driver supports ATM cards based on the Efficient "Lanai"
- * chipset such as the Speedstream 3010 and the ENI-25p.  The
- * Speedstream 3060 is currently not supported since we don't
- * have the code to drive the on-board Alcatel DSL chipset (yet).
- *
- * Thanks to Efficient for supporting this project with hardware,
- * documentation, and by answering my questions.
- *
- * Things not working yet:
- *
- * o  We don't support the Speedstream 3060 yet - this card has
- *    an on-board DSL modem chip by Alcatel and the driver will
- *    need some extra code added to handle it
- *
- * o  Note that due to limitations of the Lanai only one VCC can be
- *    in CBR at once
- *
- * o We don't currently parse the EEPROM at all.  The code is all
- *   there as per the spec, but it doesn't actually work.  I think
- *   there may be some issues with the docs.  Anyway, do NOT
- *   enable it yet - bugs in that code may actually damage your
- *   hardware!  Because of this you should hardware an ESI before
- *   trying to use this in a LANE or MPOA environment.
- *
- * o  AAL0 is stubbed in but the actual rx/tx path isn't written yet:
- *	vcc_tx_aal0() needs to send or queue a SKB
- *	vcc_tx_unqueue_aal0() needs to attempt to send queued SKBs
- *	vcc_rx_aal0() needs to handle AAL0 interrupts
- *    This isn't too much work - I just wanted to get other things
- *    done first.
- *
- * o  lanai_change_qos() isn't written yet
- *
- * o  There aren't any ioctl's yet -- I'd like to eventually support
- *    setting loopback and LED modes that way.
- *
- * o  If the segmentation engine or DMA gets shut down we should restart
- *    card as per section 17.0i.  (see lanai_reset)
- *
- * o setsockopt(SO_CIRANGE) isn't done (although despite what the
- *   API says it isn't exactly commonly implemented)
- */
-
-/* Version history:
- *   v.1.00 -- 26-JUL-2003 -- PCI/DMA updates
- *   v.0.02 -- 11-JAN-2000 -- Endian fixes
- *   v.0.01 -- 30-NOV-1999 -- Initial release
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/atmdev.h>
-#include <asm/io.h>
-#include <asm/byteorder.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-/* -------------------- TUNABLE PARAMATERS: */
-
-/*
- * Maximum number of VCIs per card.  Setting it lower could theoretically
- * save some memory, but since we allocate our vcc list with get_free_pages,
- * it's not really likely for most architectures
- */
-#define NUM_VCI			(1024)
-
-/*
- * Enable extra debugging
- */
-#define DEBUG
-/*
- * Debug _all_ register operations with card, except the memory test.
- * Also disables the timed poll to prevent extra chattiness.  This
- * isn't for normal use
- */
-#undef DEBUG_RW
-
-/*
- * The programming guide specifies a full test of the on-board SRAM
- * at initialization time.  Undefine to remove this
- */
-#define FULL_MEMORY_TEST
-
-/*
- * This is the number of (4 byte) service entries that we will
- * try to allocate at startup.  Note that we will end up with
- * one PAGE_SIZE's worth regardless of what this is set to
- */
-#define SERVICE_ENTRIES		(1024)
-/* TODO: make above a module load-time option */
-
-/*
- * We normally read the onboard EEPROM in order to discover our MAC
- * address.  Undefine to _not_ do this
- */
-/* #define READ_EEPROM */ /* ***DONT ENABLE YET*** */
-/* TODO: make above a module load-time option (also) */
-
-/*
- * Depth of TX fifo (in 128 byte units; range 2-31)
- * Smaller numbers are better for network latency
- * Larger numbers are better for PCI latency
- * I'm really sure where the best tradeoff is, but the BSD driver uses
- * 7 and it seems to work ok.
- */
-#define TX_FIFO_DEPTH		(7)
-/* TODO: make above a module load-time option */
-
-/*
- * How often (in jiffies) we will try to unstick stuck connections -
- * shouldn't need to happen much
- */
-#define LANAI_POLL_PERIOD	(10*HZ)
-/* TODO: make above a module load-time option */
-
-/*
- * When allocating an AAL5 receiving buffer, try to make it at least
- * large enough to hold this many max_sdu sized PDUs
- */
-#define AAL5_RX_MULTIPLIER	(3)
-/* TODO: make above a module load-time option */
-
-/*
- * Same for transmitting buffer
- */
-#define AAL5_TX_MULTIPLIER	(3)
-/* TODO: make above a module load-time option */
-
-/*
- * When allocating an AAL0 transmiting buffer, how many cells should fit.
- * Remember we'll end up with a PAGE_SIZE of them anyway, so this isn't
- * really critical
- */
-#define AAL0_TX_MULTIPLIER	(40)
-/* TODO: make above a module load-time option */
-
-/*
- * How large should we make the AAL0 receiving buffer.  Remember that this
- * is shared between all AAL0 VC's
- */
-#define AAL0_RX_BUFFER_SIZE	(PAGE_SIZE)
-/* TODO: make above a module load-time option */
-
-/*
- * Should we use Lanai's "powerdown" feature when no vcc's are bound?
- */
-/* #define USE_POWERDOWN */
-/* TODO: make above a module load-time option (also) */
-
-/* -------------------- DEBUGGING AIDS: */
-
-#define DEV_LABEL "lanai"
-
-#ifdef DEBUG
-
-#define DPRINTK(format, args...) \
-	printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
-#define APRINTK(truth, format, args...) \
-	do { \
-		if (unlikely(!(truth))) \
-			printk(KERN_ERR DEV_LABEL ": " format, ##args); \
-	} while (0)
-
-#else /* !DEBUG */
-
-#define DPRINTK(format, args...)
-#define APRINTK(truth, format, args...)
-
-#endif /* DEBUG */
-
-#ifdef DEBUG_RW
-#define RWDEBUG(format, args...) \
-	printk(KERN_DEBUG DEV_LABEL ": " format, ##args)
-#else /* !DEBUG_RW */
-#define RWDEBUG(format, args...)
-#endif
-
-/* -------------------- DATA DEFINITIONS: */
-
-#define LANAI_MAPPING_SIZE	(0x40000)
-#define LANAI_EEPROM_SIZE	(128)
-
-typedef int vci_t;
-typedef void __iomem *bus_addr_t;
-
-/* DMA buffer in host memory for TX, RX, or service list. */
-struct lanai_buffer {
-	u32 *start;	/* From get_free_pages */
-	u32 *end;	/* One past last byte */
-	u32 *ptr;	/* Pointer to current host location */
-	dma_addr_t dmaaddr;
-};
-
-struct lanai_vcc_stats {
-	unsigned rx_nomem;
-	union {
-		struct {
-			unsigned rx_badlen;
-			unsigned service_trash;
-			unsigned service_stream;
-			unsigned service_rxcrc;
-		} aal5;
-		struct {
-		} aal0;
-	} x;
-};
-
-struct lanai_dev;			/* Forward declaration */
-
-/*
- * This is the card-specific per-vcc data.  Note that unlike some other
- * drivers there is NOT a 1-to-1 correspondance between these and
- * atm_vcc's - each one of these represents an actual 2-way vcc, but
- * an atm_vcc can be 1-way and share with a 1-way vcc in the other
- * direction.  To make it weirder, there can even be 0-way vccs
- * bound to us, waiting to do a change_qos
- */
-struct lanai_vcc {
-	bus_addr_t vbase;		/* Base of VCC's registers */
-	struct lanai_vcc_stats stats;
-	int nref;			/* # of atm_vcc's who reference us */
-	vci_t vci;
-	struct {
-		struct lanai_buffer buf;
-		struct atm_vcc *atmvcc;	/* atm_vcc who is receiver */
-	} rx;
-	struct {
-		struct lanai_buffer buf;
-		struct atm_vcc *atmvcc;	/* atm_vcc who is transmitter */
-		int endptr;		/* last endptr from service entry */
-		struct sk_buff_head backlog;
-		void (*unqueue)(struct lanai_dev *, struct lanai_vcc *, int);
-	} tx;
-};
-
-enum lanai_type {
-	lanai2	= PCI_DEVICE_ID_EF_ATM_LANAI2,
-	lanaihb	= PCI_DEVICE_ID_EF_ATM_LANAIHB
-};
-
-struct lanai_dev_stats {
-	unsigned ovfl_trash;	/* # of cells dropped - buffer overflow */
-	unsigned vci_trash;	/* # of cells dropped - closed vci */
-	unsigned hec_err;	/* # of cells dropped - bad HEC */
-	unsigned atm_ovfl;	/* # of cells dropped - rx fifo overflow */
-	unsigned pcierr_parity_detect;
-	unsigned pcierr_serr_set;
-	unsigned pcierr_master_abort;
-	unsigned pcierr_m_target_abort;
-	unsigned pcierr_s_target_abort;
-	unsigned pcierr_master_parity;
-	unsigned service_notx;
-	unsigned service_norx;
-	unsigned service_rxnotaal5;
-	unsigned dma_reenable;
-	unsigned card_reset;
-};
-
-struct lanai_dev {
-	bus_addr_t base;
-	struct lanai_dev_stats stats;
-	struct lanai_buffer service;
-	struct lanai_vcc **vccs;
-#ifdef USE_POWERDOWN
-	int nbound;			/* number of bound vccs */
-#endif
-	enum lanai_type type;
-	vci_t num_vci;			/* Currently just NUM_VCI */
-	u8 eeprom[LANAI_EEPROM_SIZE];
-	u32 serialno, magicno;
-	struct pci_dev *pci;
-	DECLARE_BITMAP(backlog_vccs, NUM_VCI);   /* VCCs with tx backlog */
-	DECLARE_BITMAP(transmit_ready, NUM_VCI); /* VCCs with transmit space */
-	struct timer_list timer;
-	int naal0;
-	struct lanai_buffer aal0buf;	/* AAL0 RX buffers */
-	u32 conf1, conf2;		/* CONFIG[12] registers */
-	u32 status;			/* STATUS register */
-	spinlock_t endtxlock;
-	spinlock_t servicelock;
-	struct atm_vcc *cbrvcc;
-	int number;
-	int board_rev;
-/* TODO - look at race conditions with maintence of conf1/conf2 */
-/* TODO - transmit locking: should we use _irq not _irqsave? */
-/* TODO - organize above in some rational fashion (see <asm/cache.h>) */
-};
-
-/*
- * Each device has two bitmaps for each VCC (baclog_vccs and transmit_ready)
- * This function iterates one of these, calling a given function for each
- * vci with their bit set
- */
-static void vci_bitfield_iterate(struct lanai_dev *lanai,
-	const unsigned long *lp,
-	void (*func)(struct lanai_dev *,vci_t vci))
-{
-	vci_t vci;
-
-	for_each_set_bit(vci, lp, NUM_VCI)
-		func(lanai, vci);
-}
-
-/* -------------------- BUFFER  UTILITIES: */
-
-/*
- * Lanai needs DMA buffers aligned to 256 bytes of at least 1024 bytes -
- * usually any page allocation will do.  Just to be safe in case
- * PAGE_SIZE is insanely tiny, though...
- */
-#define LANAI_PAGE_SIZE   ((PAGE_SIZE >= 1024) ? PAGE_SIZE : 1024)
-
-/*
- * Allocate a buffer in host RAM for service list, RX, or TX
- * Returns buf->start==NULL if no memory
- * Note that the size will be rounded up 2^n bytes, and
- * if we can't allocate that we'll settle for something smaller
- * until minbytes
- */
-static void lanai_buf_allocate(struct lanai_buffer *buf,
-	size_t bytes, size_t minbytes, struct pci_dev *pci)
-{
-	int size;
-
-	if (bytes > (128 * 1024))	/* max lanai buffer size */
-		bytes = 128 * 1024;
-	for (size = LANAI_PAGE_SIZE; size < bytes; size *= 2)
-		;
-	if (minbytes < LANAI_PAGE_SIZE)
-		minbytes = LANAI_PAGE_SIZE;
-	do {
-		/*
-		 * Technically we could use non-consistent mappings for
-		 * everything, but the way the lanai uses DMA memory would
-		 * make that a terrific pain.  This is much simpler.
-		 */
-		buf->start = dma_alloc_coherent(&pci->dev,
-						size, &buf->dmaaddr, GFP_KERNEL);
-		if (buf->start != NULL) {	/* Success */
-			/* Lanai requires 256-byte alignment of DMA bufs */
-			APRINTK((buf->dmaaddr & ~0xFFFFFF00) == 0,
-			    "bad dmaaddr: 0x%lx\n",
-			    (unsigned long) buf->dmaaddr);
-			buf->ptr = buf->start;
-			buf->end = (u32 *)
-			    (&((unsigned char *) buf->start)[size]);
-			memset(buf->start, 0, size);
-			break;
-		}
-		size /= 2;
-	} while (size >= minbytes);
-}
-
-/* size of buffer in bytes */
-static inline size_t lanai_buf_size(const struct lanai_buffer *buf)
-{
-	return ((unsigned long) buf->end) - ((unsigned long) buf->start);
-}
-
-static void lanai_buf_deallocate(struct lanai_buffer *buf,
-	struct pci_dev *pci)
-{
-	if (buf->start != NULL) {
-		dma_free_coherent(&pci->dev, lanai_buf_size(buf),
-				  buf->start, buf->dmaaddr);
-		buf->start = buf->end = buf->ptr = NULL;
-	}
-}
-
-/* size of buffer as "card order" (0=1k .. 7=128k) */
-static int lanai_buf_size_cardorder(const struct lanai_buffer *buf)
-{
-	int order = get_order(lanai_buf_size(buf)) + (PAGE_SHIFT - 10);
-
-	/* This can only happen if PAGE_SIZE is gigantic, but just in case */
-	if (order > 7)
-		order = 7;
-	return order;
-}
-
-/* -------------------- PORT I/O UTILITIES: */
-
-/* Registers (and their bit-fields) */
-enum lanai_register {
-	Reset_Reg		= 0x00,	/* Reset; read for chip type; bits: */
-#define   RESET_GET_BOARD_REV(x)    (((x)>> 0)&0x03)	/* Board revision */
-#define   RESET_GET_BOARD_ID(x)	    (((x)>> 2)&0x03)	/* Board ID */
-#define     BOARD_ID_LANAI256		(0)	/* 25.6M adapter card */
-	Endian_Reg		= 0x04,	/* Endian setting */
-	IntStatus_Reg		= 0x08,	/* Interrupt status */
-	IntStatusMasked_Reg	= 0x0C,	/* Interrupt status (masked) */
-	IntAck_Reg		= 0x10,	/* Interrupt acknowledge */
-	IntAckMasked_Reg	= 0x14,	/* Interrupt acknowledge (masked) */
-	IntStatusSet_Reg	= 0x18,	/* Get status + enable/disable */
-	IntStatusSetMasked_Reg	= 0x1C,	/* Get status + en/di (masked) */
-	IntControlEna_Reg	= 0x20,	/* Interrupt control enable */
-	IntControlDis_Reg	= 0x24,	/* Interrupt control disable */
-	Status_Reg		= 0x28,	/* Status */
-#define   STATUS_PROMDATA	 (0x00000001)	/* PROM_DATA pin */
-#define   STATUS_WAITING	 (0x00000002)	/* Interrupt being delayed */
-#define	  STATUS_SOOL		 (0x00000004)	/* SOOL alarm */
-#define   STATUS_LOCD		 (0x00000008)	/* LOCD alarm */
-#define	  STATUS_LED		 (0x00000010)	/* LED (HAPPI) output */
-#define   STATUS_GPIN		 (0x00000020)	/* GPIN pin */
-#define   STATUS_BUTTBUSY	 (0x00000040)	/* Butt register is pending */
-	Config1_Reg		= 0x2C,	/* Config word 1; bits: */
-#define   CONFIG1_PROMDATA	 (0x00000001)	/* PROM_DATA pin */
-#define   CONFIG1_PROMCLK	 (0x00000002)	/* PROM_CLK pin */
-#define   CONFIG1_SET_READMODE(x) ((x)*0x004)	/* PCI BM reads; values: */
-#define     READMODE_PLAIN	    (0)		/*   Plain memory read */
-#define     READMODE_LINE	    (2)		/*   Memory read line */
-#define     READMODE_MULTIPLE	    (3)		/*   Memory read multiple */
-#define   CONFIG1_DMA_ENABLE	 (0x00000010)	/* Turn on DMA */
-#define   CONFIG1_POWERDOWN	 (0x00000020)	/* Turn off clocks */
-#define   CONFIG1_SET_LOOPMODE(x) ((x)*0x080)	/* Clock&loop mode; values: */
-#define     LOOPMODE_NORMAL	    (0)		/*   Normal - no loop */
-#define     LOOPMODE_TIME	    (1)
-#define     LOOPMODE_DIAG	    (2)
-#define     LOOPMODE_LINE	    (3)
-#define   CONFIG1_MASK_LOOPMODE  (0x00000180)
-#define   CONFIG1_SET_LEDMODE(x) ((x)*0x0200)	/* Mode of LED; values: */
-#define     LEDMODE_NOT_SOOL	    (0)		/*   !SOOL */
-#define	    LEDMODE_OFF		    (1)		/*   0     */
-#define	    LEDMODE_ON		    (2)		/*   1     */
-#define	    LEDMODE_NOT_LOCD	    (3)		/*   !LOCD */
-#define	    LEDMORE_GPIN	    (4)		/*   GPIN  */
-#define     LEDMODE_NOT_GPIN	    (7)		/*   !GPIN */
-#define   CONFIG1_MASK_LEDMODE	 (0x00000E00)
-#define   CONFIG1_GPOUT1	 (0x00001000)	/* Toggle for reset */
-#define   CONFIG1_GPOUT2	 (0x00002000)	/* Loopback PHY */
-#define   CONFIG1_GPOUT3	 (0x00004000)	/* Loopback lanai */
-	Config2_Reg		= 0x30,	/* Config word 2; bits: */
-#define   CONFIG2_HOWMANY	 (0x00000001)	/* >512 VCIs? */
-#define   CONFIG2_PTI7_MODE	 (0x00000002)	/* Make PTI=7 RM, not OAM */
-#define   CONFIG2_VPI_CHK_DIS	 (0x00000004)	/* Ignore RX VPI value */
-#define   CONFIG2_HEC_DROP	 (0x00000008)	/* Drop cells w/ HEC errors */
-#define   CONFIG2_VCI0_NORMAL	 (0x00000010)	/* Treat VCI=0 normally */
-#define   CONFIG2_CBR_ENABLE	 (0x00000020)	/* Deal with CBR traffic */
-#define   CONFIG2_TRASH_ALL	 (0x00000040)	/* Trashing incoming cells */
-#define   CONFIG2_TX_DISABLE	 (0x00000080)	/* Trashing outgoing cells */
-#define   CONFIG2_SET_TRASH	 (0x00000100)	/* Turn trashing on */
-	Statistics_Reg		= 0x34,	/* Statistics; bits: */
-#define   STATS_GET_FIFO_OVFL(x)    (((x)>> 0)&0xFF)	/* FIFO overflowed */
-#define   STATS_GET_HEC_ERR(x)      (((x)>> 8)&0xFF)	/* HEC was bad */
-#define   STATS_GET_BAD_VCI(x)      (((x)>>16)&0xFF)	/* VCI not open */
-#define   STATS_GET_BUF_OVFL(x)     (((x)>>24)&0xFF)	/* VCC buffer full */
-	ServiceStuff_Reg	= 0x38,	/* Service stuff; bits: */
-#define   SSTUFF_SET_SIZE(x) ((x)*0x20000000)	/* size of service buffer */
-#define   SSTUFF_SET_ADDR(x)	    ((x)>>8)	/* set address of buffer */
-	ServWrite_Reg		= 0x3C,	/* ServWrite Pointer */
-	ServRead_Reg		= 0x40,	/* ServRead Pointer */
-	TxDepth_Reg		= 0x44,	/* FIFO Transmit Depth */
-	Butt_Reg		= 0x48,	/* Butt register */
-	CBR_ICG_Reg		= 0x50,
-	CBR_PTR_Reg		= 0x54,
-	PingCount_Reg		= 0x58,	/* Ping count */
-	DMA_Addr_Reg		= 0x5C	/* DMA address */
-};
-
-static inline bus_addr_t reg_addr(const struct lanai_dev *lanai,
-	enum lanai_register reg)
-{
-	return lanai->base + reg;
-}
-
-static inline u32 reg_read(const struct lanai_dev *lanai,
-	enum lanai_register reg)
-{
-	u32 t;
-	t = readl(reg_addr(lanai, reg));
-	RWDEBUG("R [0x%08X] 0x%02X = 0x%08X\n", (unsigned int) lanai->base,
-	    (int) reg, t);
-	return t;
-}
-
-static inline void reg_write(const struct lanai_dev *lanai, u32 val,
-	enum lanai_register reg)
-{
-	RWDEBUG("W [0x%08X] 0x%02X < 0x%08X\n", (unsigned int) lanai->base,
-	    (int) reg, val);
-	writel(val, reg_addr(lanai, reg));
-}
-
-static inline void conf1_write(const struct lanai_dev *lanai)
-{
-	reg_write(lanai, lanai->conf1, Config1_Reg);
-}
-
-static inline void conf2_write(const struct lanai_dev *lanai)
-{
-	reg_write(lanai, lanai->conf2, Config2_Reg);
-}
-
-/* Same as conf2_write(), but defers I/O if we're powered down */
-static inline void conf2_write_if_powerup(const struct lanai_dev *lanai)
-{
-#ifdef USE_POWERDOWN
-	if (unlikely((lanai->conf1 & CONFIG1_POWERDOWN) != 0))
-		return;
-#endif /* USE_POWERDOWN */
-	conf2_write(lanai);
-}
-
-static inline void reset_board(const struct lanai_dev *lanai)
-{
-	DPRINTK("about to reset board\n");
-	reg_write(lanai, 0, Reset_Reg);
-	/*
-	 * If we don't delay a little while here then we can end up
-	 * leaving the card in a VERY weird state and lock up the
-	 * PCI bus.  This isn't documented anywhere but I've convinced
-	 * myself after a lot of painful experimentation
-	 */
-	udelay(5);
-}
-
-/* -------------------- CARD SRAM UTILITIES: */
-
-/* The SRAM is mapped into normal PCI memory space - the only catch is
- * that it is only 16-bits wide but must be accessed as 32-bit.  The
- * 16 high bits will be zero.  We don't hide this, since they get
- * programmed mostly like discrete registers anyway
- */
-#define SRAM_START (0x20000)
-#define SRAM_BYTES (0x20000)	/* Again, half don't really exist */
-
-static inline bus_addr_t sram_addr(const struct lanai_dev *lanai, int offset)
-{
-	return lanai->base + SRAM_START + offset;
-}
-
-static inline u32 sram_read(const struct lanai_dev *lanai, int offset)
-{
-	return readl(sram_addr(lanai, offset));
-}
-
-static inline void sram_write(const struct lanai_dev *lanai,
-	u32 val, int offset)
-{
-	writel(val, sram_addr(lanai, offset));
-}
-
-static int sram_test_word(const struct lanai_dev *lanai, int offset,
-			  u32 pattern)
-{
-	u32 readback;
-	sram_write(lanai, pattern, offset);
-	readback = sram_read(lanai, offset);
-	if (likely(readback == pattern))
-		return 0;
-	printk(KERN_ERR DEV_LABEL
-	    "(itf %d): SRAM word at %d bad: wrote 0x%X, read 0x%X\n",
-	    lanai->number, offset,
-	    (unsigned int) pattern, (unsigned int) readback);
-	return -EIO;
-}
-
-static int sram_test_pass(const struct lanai_dev *lanai, u32 pattern)
-{
-	int offset, result = 0;
-	for (offset = 0; offset < SRAM_BYTES && result == 0; offset += 4)
-		result = sram_test_word(lanai, offset, pattern);
-	return result;
-}
-
-static int sram_test_and_clear(const struct lanai_dev *lanai)
-{
-#ifdef FULL_MEMORY_TEST
-	int result;
-	DPRINTK("testing SRAM\n");
-	if ((result = sram_test_pass(lanai, 0x5555)) != 0)
-		return result;
-	if ((result = sram_test_pass(lanai, 0xAAAA)) != 0)
-		return result;
-#endif
-	DPRINTK("clearing SRAM\n");
-	return sram_test_pass(lanai, 0x0000);
-}
-
-/* -------------------- CARD-BASED VCC TABLE UTILITIES: */
-
-/* vcc table */
-enum lanai_vcc_offset {
-	vcc_rxaddr1		= 0x00,	/* Location1, plus bits: */
-#define   RXADDR1_SET_SIZE(x) ((x)*0x0000100)	/* size of RX buffer */
-#define   RXADDR1_SET_RMMODE(x) ((x)*0x00800)	/* RM cell action; values: */
-#define     RMMODE_TRASH	  (0)		/*   discard */
-#define     RMMODE_PRESERVE	  (1)		/*   input as AAL0 */
-#define     RMMODE_PIPE		  (2)		/*   pipe to coscheduler */
-#define     RMMODE_PIPEALL	  (3)		/*   pipe non-RM too */
-#define   RXADDR1_OAM_PRESERVE	 (0x00002000)	/* Input OAM cells as AAL0 */
-#define   RXADDR1_SET_MODE(x) ((x)*0x0004000)	/* Reassembly mode */
-#define     RXMODE_TRASH	  (0)		/*   discard */
-#define     RXMODE_AAL0		  (1)		/*   non-AAL5 mode */
-#define     RXMODE_AAL5		  (2)		/*   AAL5, intr. each PDU */
-#define     RXMODE_AAL5_STREAM	  (3)		/*   AAL5 w/o per-PDU intr */
-	vcc_rxaddr2		= 0x04,	/* Location2 */
-	vcc_rxcrc1		= 0x08,	/* RX CRC claculation space */
-	vcc_rxcrc2		= 0x0C,
-	vcc_rxwriteptr		= 0x10, /* RX writeptr, plus bits: */
-#define   RXWRITEPTR_LASTEFCI	 (0x00002000)	/* Last PDU had EFCI bit */
-#define   RXWRITEPTR_DROPPING	 (0x00004000)	/* Had error, dropping */
-#define   RXWRITEPTR_TRASHING	 (0x00008000)	/* Trashing */
-	vcc_rxbufstart		= 0x14,	/* RX bufstart, plus bits: */
-#define   RXBUFSTART_CLP	 (0x00004000)
-#define   RXBUFSTART_CI		 (0x00008000)
-	vcc_rxreadptr		= 0x18,	/* RX readptr */
-	vcc_txicg		= 0x1C, /* TX ICG */
-	vcc_txaddr1		= 0x20,	/* Location1, plus bits: */
-#define   TXADDR1_SET_SIZE(x) ((x)*0x0000100)	/* size of TX buffer */
-#define   TXADDR1_ABR		 (0x00008000)	/* use ABR (doesn't work) */
-	vcc_txaddr2		= 0x24,	/* Location2 */
-	vcc_txcrc1		= 0x28,	/* TX CRC claculation space */
-	vcc_txcrc2		= 0x2C,
-	vcc_txreadptr		= 0x30, /* TX Readptr, plus bits: */
-#define   TXREADPTR_GET_PTR(x) ((x)&0x01FFF)
-#define   TXREADPTR_MASK_DELTA	(0x0000E000)	/* ? */
-	vcc_txendptr		= 0x34, /* TX Endptr, plus bits: */
-#define   TXENDPTR_CLP		(0x00002000)
-#define   TXENDPTR_MASK_PDUMODE	(0x0000C000)	/* PDU mode; values: */
-#define     PDUMODE_AAL0	 (0*0x04000)
-#define     PDUMODE_AAL5	 (2*0x04000)
-#define     PDUMODE_AAL5STREAM	 (3*0x04000)
-	vcc_txwriteptr		= 0x38,	/* TX Writeptr */
-#define   TXWRITEPTR_GET_PTR(x) ((x)&0x1FFF)
-	vcc_txcbr_next		= 0x3C	/* # of next CBR VCI in ring */
-#define   TXCBR_NEXT_BOZO	(0x00008000)	/* "bozo bit" */
-};
-
-#define CARDVCC_SIZE	(0x40)
-
-static inline bus_addr_t cardvcc_addr(const struct lanai_dev *lanai,
-	vci_t vci)
-{
-	return sram_addr(lanai, vci * CARDVCC_SIZE);
-}
-
-static inline u32 cardvcc_read(const struct lanai_vcc *lvcc,
-	enum lanai_vcc_offset offset)
-{
-	u32 val;
-	APRINTK(lvcc->vbase != NULL, "cardvcc_read: unbound vcc!\n");
-	val= readl(lvcc->vbase + offset);
-	RWDEBUG("VR vci=%04d 0x%02X = 0x%08X\n",
-	    lvcc->vci, (int) offset, val);
-	return val;
-}
-
-static inline void cardvcc_write(const struct lanai_vcc *lvcc,
-	u32 val, enum lanai_vcc_offset offset)
-{
-	APRINTK(lvcc->vbase != NULL, "cardvcc_write: unbound vcc!\n");
-	APRINTK((val & ~0xFFFF) == 0,
-	    "cardvcc_write: bad val 0x%X (vci=%d, addr=0x%02X)\n",
-	    (unsigned int) val, lvcc->vci, (unsigned int) offset);
-	RWDEBUG("VW vci=%04d 0x%02X > 0x%08X\n",
-	    lvcc->vci, (unsigned int) offset, (unsigned int) val);
-	writel(val, lvcc->vbase + offset);
-}
-
-/* -------------------- COMPUTE SIZE OF AN AAL5 PDU: */
-
-/* How many bytes will an AAL5 PDU take to transmit - remember that:
- *   o  we need to add 8 bytes for length, CPI, UU, and CRC
- *   o  we need to round up to 48 bytes for cells
- */
-static inline int aal5_size(int size)
-{
-	int cells = (size + 8 + 47) / 48;
-	return cells * 48;
-}
-
-/* -------------------- FREE AN ATM SKB: */
-
-static inline void lanai_free_skb(struct atm_vcc *atmvcc, struct sk_buff *skb)
-{
-	if (atmvcc->pop != NULL)
-		atmvcc->pop(atmvcc, skb);
-	else
-		dev_kfree_skb_any(skb);
-}
-
-/* -------------------- TURN VCCS ON AND OFF: */
-
-static void host_vcc_start_rx(const struct lanai_vcc *lvcc)
-{
-	u32 addr1;
-	if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) {
-		dma_addr_t dmaaddr = lvcc->rx.buf.dmaaddr;
-		cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc1);
-		cardvcc_write(lvcc, 0xFFFF, vcc_rxcrc2);
-		cardvcc_write(lvcc, 0, vcc_rxwriteptr);
-		cardvcc_write(lvcc, 0, vcc_rxbufstart);
-		cardvcc_write(lvcc, 0, vcc_rxreadptr);
-		cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_rxaddr2);
-		addr1 = ((dmaaddr >> 8) & 0xFF) |
-		    RXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->rx.buf))|
-		    RXADDR1_SET_RMMODE(RMMODE_TRASH) |	/* ??? */
-		 /* RXADDR1_OAM_PRESERVE |	--- no OAM support yet */
-		    RXADDR1_SET_MODE(RXMODE_AAL5);
-	} else
-		addr1 = RXADDR1_SET_RMMODE(RMMODE_PRESERVE) | /* ??? */
-		    RXADDR1_OAM_PRESERVE |		      /* ??? */
-		    RXADDR1_SET_MODE(RXMODE_AAL0);
-	/* This one must be last! */
-	cardvcc_write(lvcc, addr1, vcc_rxaddr1);
-}
-
-static void host_vcc_start_tx(const struct lanai_vcc *lvcc)
-{
-	dma_addr_t dmaaddr = lvcc->tx.buf.dmaaddr;
-	cardvcc_write(lvcc, 0, vcc_txicg);
-	cardvcc_write(lvcc, 0xFFFF, vcc_txcrc1);
-	cardvcc_write(lvcc, 0xFFFF, vcc_txcrc2);
-	cardvcc_write(lvcc, 0, vcc_txreadptr);
-	cardvcc_write(lvcc, 0, vcc_txendptr);
-	cardvcc_write(lvcc, 0, vcc_txwriteptr);
-	cardvcc_write(lvcc,
-		(lvcc->tx.atmvcc->qos.txtp.traffic_class == ATM_CBR) ?
-		TXCBR_NEXT_BOZO | lvcc->vci : 0, vcc_txcbr_next);
-	cardvcc_write(lvcc, (dmaaddr >> 16) & 0xFFFF, vcc_txaddr2);
-	cardvcc_write(lvcc,
-	    ((dmaaddr >> 8) & 0xFF) |
-	    TXADDR1_SET_SIZE(lanai_buf_size_cardorder(&lvcc->tx.buf)),
-	    vcc_txaddr1);
-}
-
-/* Shutdown receiving on card */
-static void lanai_shutdown_rx_vci(const struct lanai_vcc *lvcc)
-{
-	if (lvcc->vbase == NULL)	/* We were never bound to a VCI */
-		return;
-	/* 15.1.1 - set to trashing, wait one cell time (15us) */
-	cardvcc_write(lvcc,
-	    RXADDR1_SET_RMMODE(RMMODE_TRASH) |
-	    RXADDR1_SET_MODE(RXMODE_TRASH), vcc_rxaddr1);
-	udelay(15);
-	/* 15.1.2 - clear rest of entries */
-	cardvcc_write(lvcc, 0, vcc_rxaddr2);
-	cardvcc_write(lvcc, 0, vcc_rxcrc1);
-	cardvcc_write(lvcc, 0, vcc_rxcrc2);
-	cardvcc_write(lvcc, 0, vcc_rxwriteptr);
-	cardvcc_write(lvcc, 0, vcc_rxbufstart);
-	cardvcc_write(lvcc, 0, vcc_rxreadptr);
-}
-
-/* Shutdown transmitting on card.
- * Unfortunately the lanai needs us to wait until all the data
- * drains out of the buffer before we can dealloc it, so this
- * can take a while -- up to 370ms for a full 128KB buffer
- * assuming everone else is quiet.  In theory the time is
- * boundless if there's a CBR VCC holding things up.
- */
-static void lanai_shutdown_tx_vci(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc)
-{
-	struct sk_buff *skb;
-	unsigned long flags, timeout;
-	int read, write, lastread = -1;
-
-	if (lvcc->vbase == NULL)	/* We were never bound to a VCI */
-		return;
-	/* 15.2.1 - wait for queue to drain */
-	while ((skb = skb_dequeue(&lvcc->tx.backlog)) != NULL)
-		lanai_free_skb(lvcc->tx.atmvcc, skb);
-	read_lock_irqsave(&vcc_sklist_lock, flags);
-	__clear_bit(lvcc->vci, lanai->backlog_vccs);
-	read_unlock_irqrestore(&vcc_sklist_lock, flags);
-	/*
-	 * We need to wait for the VCC to drain but don't wait forever.  We
-	 * give each 1K of buffer size 1/128th of a second to clear out.
-	 * TODO: maybe disable CBR if we're about to timeout?
-	 */
-	timeout = jiffies +
-	    (((lanai_buf_size(&lvcc->tx.buf) / 1024) * HZ) >> 7);
-	write = TXWRITEPTR_GET_PTR(cardvcc_read(lvcc, vcc_txwriteptr));
-	for (;;) {
-		read = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
-		if (read == write &&	   /* Is TX buffer empty? */
-		    (lvcc->tx.atmvcc->qos.txtp.traffic_class != ATM_CBR ||
-		    (cardvcc_read(lvcc, vcc_txcbr_next) &
-		    TXCBR_NEXT_BOZO) == 0))
-			break;
-		if (read != lastread) {	   /* Has there been any progress? */
-			lastread = read;
-			timeout += HZ / 10;
-		}
-		if (unlikely(time_after(jiffies, timeout))) {
-			printk(KERN_ERR DEV_LABEL "(itf %d): Timed out on "
-			    "backlog closing vci %d\n",
-			    lvcc->tx.atmvcc->dev->number, lvcc->vci);
-			DPRINTK("read, write = %d, %d\n", read, write);
-			break;
-		}
-		msleep(40);
-	}
-	/* 15.2.2 - clear out all tx registers */
-	cardvcc_write(lvcc, 0, vcc_txreadptr);
-	cardvcc_write(lvcc, 0, vcc_txwriteptr);
-	cardvcc_write(lvcc, 0, vcc_txendptr);
-	cardvcc_write(lvcc, 0, vcc_txcrc1);
-	cardvcc_write(lvcc, 0, vcc_txcrc2);
-	cardvcc_write(lvcc, 0, vcc_txaddr2);
-	cardvcc_write(lvcc, 0, vcc_txaddr1);
-}
-
-/* -------------------- MANAGING AAL0 RX BUFFER: */
-
-static inline int aal0_buffer_allocate(struct lanai_dev *lanai)
-{
-	DPRINTK("aal0_buffer_allocate: allocating AAL0 RX buffer\n");
-	lanai_buf_allocate(&lanai->aal0buf, AAL0_RX_BUFFER_SIZE, 80,
-			   lanai->pci);
-	return (lanai->aal0buf.start == NULL) ? -ENOMEM : 0;
-}
-
-static inline void aal0_buffer_free(struct lanai_dev *lanai)
-{
-	DPRINTK("aal0_buffer_allocate: freeing AAL0 RX buffer\n");
-	lanai_buf_deallocate(&lanai->aal0buf, lanai->pci);
-}
-
-/* -------------------- EEPROM UTILITIES: */
-
-/* Offsets of data in the EEPROM */
-#define EEPROM_COPYRIGHT	(0)
-#define EEPROM_COPYRIGHT_LEN	(44)
-#define EEPROM_CHECKSUM		(62)
-#define EEPROM_CHECKSUM_REV	(63)
-#define EEPROM_MAC		(64)
-#define EEPROM_MAC_REV		(70)
-#define EEPROM_SERIAL		(112)
-#define EEPROM_SERIAL_REV	(116)
-#define EEPROM_MAGIC		(120)
-#define EEPROM_MAGIC_REV	(124)
-
-#define EEPROM_MAGIC_VALUE	(0x5AB478D2)
-
-#ifndef READ_EEPROM
-
-/* Stub functions to use if EEPROM reading is disabled */
-static int eeprom_read(struct lanai_dev *lanai)
-{
-	printk(KERN_INFO DEV_LABEL "(itf %d): *NOT* reading EEPROM\n",
-	    lanai->number);
-	memset(&lanai->eeprom[EEPROM_MAC], 0, 6);
-	return 0;
-}
-
-static int eeprom_validate(struct lanai_dev *lanai)
-{
-	lanai->serialno = 0;
-	lanai->magicno = EEPROM_MAGIC_VALUE;
-	return 0;
-}
-
-#else /* READ_EEPROM */
-
-static int eeprom_read(struct lanai_dev *lanai)
-{
-	int i, address;
-	u8 data;
-	u32 tmp;
-#define set_config1(x)   do { lanai->conf1 = x; conf1_write(lanai); \
-			    } while (0)
-#define clock_h()	 set_config1(lanai->conf1 | CONFIG1_PROMCLK)
-#define clock_l()	 set_config1(lanai->conf1 &~ CONFIG1_PROMCLK)
-#define data_h()	 set_config1(lanai->conf1 | CONFIG1_PROMDATA)
-#define data_l()	 set_config1(lanai->conf1 &~ CONFIG1_PROMDATA)
-#define pre_read()	 do { data_h(); clock_h(); udelay(5); } while (0)
-#define read_pin()	 (reg_read(lanai, Status_Reg) & STATUS_PROMDATA)
-#define send_stop()	 do { data_l(); udelay(5); clock_h(); udelay(5); \
-			      data_h(); udelay(5); } while (0)
-	/* start with both clock and data high */
-	data_h(); clock_h(); udelay(5);
-	for (address = 0; address < LANAI_EEPROM_SIZE; address++) {
-		data = (address << 1) | 1;	/* Command=read + address */
-		/* send start bit */
-		data_l(); udelay(5);
-		clock_l(); udelay(5);
-		for (i = 128; i != 0; i >>= 1) {   /* write command out */
-			tmp = (lanai->conf1 & ~CONFIG1_PROMDATA) |
-			    ((data & i) ? CONFIG1_PROMDATA : 0);
-			if (lanai->conf1 != tmp) {
-				set_config1(tmp);
-				udelay(5);	/* Let new data settle */
-			}
-			clock_h(); udelay(5); clock_l(); udelay(5);
-		}
-		/* look for ack */
-		data_h(); clock_h(); udelay(5);
-		if (read_pin() != 0)
-			goto error;	/* No ack seen */
-		clock_l(); udelay(5);
-		/* read back result */
-		for (data = 0, i = 7; i >= 0; i--) {
-			data_h(); clock_h(); udelay(5);
-			data = (data << 1) | !!read_pin();
-			clock_l(); udelay(5);
-		}
-		/* look again for ack */
-		data_h(); clock_h(); udelay(5);
-		if (read_pin() == 0)
-			goto error;	/* Spurious ack */
-		clock_l(); udelay(5);
-		send_stop();
-		lanai->eeprom[address] = data;
-		DPRINTK("EEPROM 0x%04X %02X\n",
-		    (unsigned int) address, (unsigned int) data);
-	}
-	return 0;
-    error:
-	clock_l(); udelay(5);		/* finish read */
-	send_stop();
-	printk(KERN_ERR DEV_LABEL "(itf %d): error reading EEPROM byte %d\n",
-	    lanai->number, address);
-	return -EIO;
-#undef set_config1
-#undef clock_h
-#undef clock_l
-#undef data_h
-#undef data_l
-#undef pre_read
-#undef read_pin
-#undef send_stop
-}
-
-/* read a big-endian 4-byte value out of eeprom */
-static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address)
-{
-	return be32_to_cpup((const u32 *) &lanai->eeprom[address]);
-}
-
-/* Checksum/validate EEPROM contents */
-static int eeprom_validate(struct lanai_dev *lanai)
-{
-	int i, s;
-	u32 v;
-	const u8 *e = lanai->eeprom;
-#ifdef DEBUG
-	/* First, see if we can get an ASCIIZ string out of the copyright */
-	for (i = EEPROM_COPYRIGHT;
-	    i < (EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN); i++)
-		if (e[i] < 0x20 || e[i] > 0x7E)
-			break;
-	if ( i != EEPROM_COPYRIGHT &&
-	    i != EEPROM_COPYRIGHT + EEPROM_COPYRIGHT_LEN && e[i] == '\0')
-		DPRINTK("eeprom: copyright = \"%s\"\n",
-		    (char *) &e[EEPROM_COPYRIGHT]);
-	else
-		DPRINTK("eeprom: copyright not found\n");
-#endif
-	/* Validate checksum */
-	for (i = s = 0; i < EEPROM_CHECKSUM; i++)
-		s += e[i];
-	s &= 0xFF;
-	if (s != e[EEPROM_CHECKSUM]) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM checksum bad "
-		    "(wanted 0x%02X, got 0x%02X)\n", lanai->number,
-		    (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM]);
-		return -EIO;
-	}
-	s ^= 0xFF;
-	if (s != e[EEPROM_CHECKSUM_REV]) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM inverse checksum "
-		    "bad (wanted 0x%02X, got 0x%02X)\n", lanai->number,
-		    (unsigned int) s, (unsigned int) e[EEPROM_CHECKSUM_REV]);
-		return -EIO;
-	}
-	/* Verify MAC address */
-	for (i = 0; i < 6; i++)
-		if ((e[EEPROM_MAC + i] ^ e[EEPROM_MAC_REV + i]) != 0xFF) {
-			printk(KERN_ERR DEV_LABEL
-			    "(itf %d) : EEPROM MAC addresses don't match "
-			    "(0x%02X, inverse 0x%02X)\n", lanai->number,
-			    (unsigned int) e[EEPROM_MAC + i],
-			    (unsigned int) e[EEPROM_MAC_REV + i]);
-			return -EIO;
-		}
-	DPRINTK("eeprom: MAC address = %pM\n", &e[EEPROM_MAC]);
-	/* Verify serial number */
-	lanai->serialno = eeprom_be4(lanai, EEPROM_SERIAL);
-	v = eeprom_be4(lanai, EEPROM_SERIAL_REV);
-	if ((lanai->serialno ^ v) != 0xFFFFFFFF) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM serial numbers "
-		    "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
-		    (unsigned int) lanai->serialno, (unsigned int) v);
-		return -EIO;
-	}
-	DPRINTK("eeprom: Serial number = %d\n", (unsigned int) lanai->serialno);
-	/* Verify magic number */
-	lanai->magicno = eeprom_be4(lanai, EEPROM_MAGIC);
-	v = eeprom_be4(lanai, EEPROM_MAGIC_REV);
-	if ((lanai->magicno ^ v) != 0xFFFFFFFF) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): EEPROM magic numbers "
-		    "don't match (0x%08X, inverse 0x%08X)\n", lanai->number,
-		    lanai->magicno, v);
-		return -EIO;
-	}
-	DPRINTK("eeprom: Magic number = 0x%08X\n", lanai->magicno);
-	if (lanai->magicno != EEPROM_MAGIC_VALUE)
-		printk(KERN_WARNING DEV_LABEL "(itf %d): warning - EEPROM "
-		    "magic not what expected (got 0x%08X, not 0x%08X)\n",
-		    lanai->number, (unsigned int) lanai->magicno,
-		    (unsigned int) EEPROM_MAGIC_VALUE);
-	return 0;
-}
-
-#endif /* READ_EEPROM */
-
-static inline const u8 *eeprom_mac(const struct lanai_dev *lanai)
-{
-	return &lanai->eeprom[EEPROM_MAC];
-}
-
-/* -------------------- INTERRUPT HANDLING UTILITIES: */
-
-/* Interrupt types */
-#define INT_STATS	(0x00000002)	/* Statistics counter overflow */
-#define INT_SOOL	(0x00000004)	/* SOOL changed state */
-#define INT_LOCD	(0x00000008)	/* LOCD changed state */
-#define INT_LED		(0x00000010)	/* LED (HAPPI) changed state */
-#define INT_GPIN	(0x00000020)	/* GPIN changed state */
-#define INT_PING	(0x00000040)	/* PING_COUNT fulfilled */
-#define INT_WAKE	(0x00000080)	/* Lanai wants bus */
-#define INT_CBR0	(0x00000100)	/* CBR sched hit VCI 0 */
-#define INT_LOCK	(0x00000200)	/* Service list overflow */
-#define INT_MISMATCH	(0x00000400)	/* TX magic list mismatch */
-#define INT_AAL0_STR	(0x00000800)	/* Non-AAL5 buffer half filled */
-#define INT_AAL0	(0x00001000)	/* Non-AAL5 data available */
-#define INT_SERVICE	(0x00002000)	/* Service list entries available */
-#define INT_TABORTSENT	(0x00004000)	/* Target abort sent by lanai */
-#define INT_TABORTBM	(0x00008000)	/* Abort rcv'd as bus master */
-#define INT_TIMEOUTBM	(0x00010000)	/* No response to bus master */
-#define INT_PCIPARITY	(0x00020000)	/* Parity error on PCI */
-
-/* Sets of the above */
-#define INT_ALL		(0x0003FFFE)	/* All interrupts */
-#define INT_STATUS	(0x0000003C)	/* Some status pin changed */
-#define INT_DMASHUT	(0x00038000)	/* DMA engine got shut down */
-#define INT_SEGSHUT	(0x00000700)	/* Segmentation got shut down */
-
-static inline u32 intr_pending(const struct lanai_dev *lanai)
-{
-	return reg_read(lanai, IntStatusMasked_Reg);
-}
-
-static inline void intr_enable(const struct lanai_dev *lanai, u32 i)
-{
-	reg_write(lanai, i, IntControlEna_Reg);
-}
-
-static inline void intr_disable(const struct lanai_dev *lanai, u32 i)
-{
-	reg_write(lanai, i, IntControlDis_Reg);
-}
-
-/* -------------------- CARD/PCI STATUS: */
-
-static void status_message(int itf, const char *name, int status)
-{
-	static const char *onoff[2] = { "off to on", "on to off" };
-	printk(KERN_INFO DEV_LABEL "(itf %d): %s changed from %s\n",
-	    itf, name, onoff[!status]);
-}
-
-static void lanai_check_status(struct lanai_dev *lanai)
-{
-	u32 new = reg_read(lanai, Status_Reg);
-	u32 changes = new ^ lanai->status;
-	lanai->status = new;
-#define e(flag, name) \
-		if (changes & flag) \
-			status_message(lanai->number, name, new & flag)
-	e(STATUS_SOOL, "SOOL");
-	e(STATUS_LOCD, "LOCD");
-	e(STATUS_LED, "LED");
-	e(STATUS_GPIN, "GPIN");
-#undef e
-}
-
-static void pcistatus_got(int itf, const char *name)
-{
-	printk(KERN_INFO DEV_LABEL "(itf %d): PCI got %s error\n", itf, name);
-}
-
-static void pcistatus_check(struct lanai_dev *lanai, int clearonly)
-{
-	u16 s;
-	int result;
-	result = pci_read_config_word(lanai->pci, PCI_STATUS, &s);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't read PCI_STATUS: "
-		    "%d\n", lanai->number, result);
-		return;
-	}
-	s &= PCI_STATUS_DETECTED_PARITY | PCI_STATUS_SIG_SYSTEM_ERROR |
-	    PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT |
-	    PCI_STATUS_SIG_TARGET_ABORT | PCI_STATUS_PARITY;
-	if (s == 0)
-		return;
-	result = pci_write_config_word(lanai->pci, PCI_STATUS, s);
-	if (result != PCIBIOS_SUCCESSFUL)
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't write PCI_STATUS: "
-		    "%d\n", lanai->number, result);
-	if (clearonly)
-		return;
-#define e(flag, name, stat) \
-		if (s & flag) { \
-			pcistatus_got(lanai->number, name); \
-			++lanai->stats.pcierr_##stat; \
-		}
-	e(PCI_STATUS_DETECTED_PARITY, "parity", parity_detect);
-	e(PCI_STATUS_SIG_SYSTEM_ERROR, "signalled system", serr_set);
-	e(PCI_STATUS_REC_MASTER_ABORT, "master", master_abort);
-	e(PCI_STATUS_REC_TARGET_ABORT, "master target", m_target_abort);
-	e(PCI_STATUS_SIG_TARGET_ABORT, "slave", s_target_abort);
-	e(PCI_STATUS_PARITY, "master parity", master_parity);
-#undef e
-}
-
-/* -------------------- VCC TX BUFFER UTILITIES: */
-
-/* space left in tx buffer in bytes */
-static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr)
-{
-	int r;
-	r = endptr * 16;
-	r -= ((unsigned long) lvcc->tx.buf.ptr) -
-	    ((unsigned long) lvcc->tx.buf.start);
-	r -= 16;	/* Leave "bubble" - if start==end it looks empty */
-	if (r < 0)
-		r += lanai_buf_size(&lvcc->tx.buf);
-	return r;
-}
-
-/* test if VCC is currently backlogged */
-static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc)
-{
-	return !skb_queue_empty(&lvcc->tx.backlog);
-}
-
-/* Bit fields in the segmentation buffer descriptor */
-#define DESCRIPTOR_MAGIC	(0xD0000000)
-#define DESCRIPTOR_AAL5		(0x00008000)
-#define DESCRIPTOR_AAL5_STREAM	(0x00004000)
-#define DESCRIPTOR_CLP		(0x00002000)
-
-/* Add 32-bit descriptor with its padding */
-static inline void vcc_tx_add_aal5_descriptor(struct lanai_vcc *lvcc,
-	u32 flags, int len)
-{
-	int pos;
-	APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad ptr=%p\n", lvcc->tx.buf.ptr);
-	lvcc->tx.buf.ptr += 4;	/* Hope the values REALLY don't matter */
-	pos = ((unsigned char *) lvcc->tx.buf.ptr) -
-	    (unsigned char *) lvcc->tx.buf.start;
-	APRINTK((pos & ~0x0001FFF0) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad pos (%d) before, vci=%d, "
-	    "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
-	    lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
-	pos = (pos + len) & (lanai_buf_size(&lvcc->tx.buf) - 1);
-	APRINTK((pos & ~0x0001FFF0) == 0,
-	    "vcc_tx_add_aal5_descriptor: bad pos (%d) after, vci=%d, "
-	    "start,ptr,end=%p,%p,%p\n", pos, lvcc->vci,
-	    lvcc->tx.buf.start, lvcc->tx.buf.ptr, lvcc->tx.buf.end);
-	lvcc->tx.buf.ptr[-1] =
-	    cpu_to_le32(DESCRIPTOR_MAGIC | DESCRIPTOR_AAL5 |
-	    ((lvcc->tx.atmvcc->atm_options & ATM_ATMOPT_CLP) ?
-	    DESCRIPTOR_CLP : 0) | flags | pos >> 4);
-	if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
-		lvcc->tx.buf.ptr = lvcc->tx.buf.start;
-}
-
-/* Add 32-bit AAL5 trailer and leave room for its CRC */
-static inline void vcc_tx_add_aal5_trailer(struct lanai_vcc *lvcc,
-	int len, int cpi, int uu)
-{
-	APRINTK((((unsigned long) lvcc->tx.buf.ptr) & 15) == 8,
-	    "vcc_tx_add_aal5_trailer: bad ptr=%p\n", lvcc->tx.buf.ptr);
-	lvcc->tx.buf.ptr += 2;
-	lvcc->tx.buf.ptr[-2] = cpu_to_be32((uu << 24) | (cpi << 16) | len);
-	if (lvcc->tx.buf.ptr >= lvcc->tx.buf.end)
-		lvcc->tx.buf.ptr = lvcc->tx.buf.start;
-}
-
-static inline void vcc_tx_memcpy(struct lanai_vcc *lvcc,
-	const unsigned char *src, int n)
-{
-	unsigned char *e;
-	int m;
-	e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
-	m = e - (unsigned char *) lvcc->tx.buf.end;
-	if (m < 0)
-		m = 0;
-	memcpy(lvcc->tx.buf.ptr, src, n - m);
-	if (m != 0) {
-		memcpy(lvcc->tx.buf.start, src + n - m, m);
-		e = ((unsigned char *) lvcc->tx.buf.start) + m;
-	}
-	lvcc->tx.buf.ptr = (u32 *) e;
-}
-
-static inline void vcc_tx_memzero(struct lanai_vcc *lvcc, int n)
-{
-	unsigned char *e;
-	int m;
-	if (n == 0)
-		return;
-	e = ((unsigned char *) lvcc->tx.buf.ptr) + n;
-	m = e - (unsigned char *) lvcc->tx.buf.end;
-	if (m < 0)
-		m = 0;
-	memset(lvcc->tx.buf.ptr, 0, n - m);
-	if (m != 0) {
-		memset(lvcc->tx.buf.start, 0, m);
-		e = ((unsigned char *) lvcc->tx.buf.start) + m;
-	}
-	lvcc->tx.buf.ptr = (u32 *) e;
-}
-
-/* Update "butt" register to specify new WritePtr */
-static inline void lanai_endtx(struct lanai_dev *lanai,
-	const struct lanai_vcc *lvcc)
-{
-	int i, ptr = ((unsigned char *) lvcc->tx.buf.ptr) -
-	    (unsigned char *) lvcc->tx.buf.start;
-	APRINTK((ptr & ~0x0001FFF0) == 0,
-	    "lanai_endtx: bad ptr (%d), vci=%d, start,ptr,end=%p,%p,%p\n",
-	    ptr, lvcc->vci, lvcc->tx.buf.start, lvcc->tx.buf.ptr,
-	    lvcc->tx.buf.end);
-
-	/*
-	 * Since the "butt register" is a shared resounce on the card we
-	 * serialize all accesses to it through this spinlock.  This is
-	 * mostly just paranoia since the register is rarely "busy" anyway
-	 * but is needed for correctness.
-	 */
-	spin_lock(&lanai->endtxlock);
-	/*
-	 * We need to check if the "butt busy" bit is set before
-	 * updating the butt register.  In theory this should
-	 * never happen because the ATM card is plenty fast at
-	 * updating the register.  Still, we should make sure
-	 */
-	for (i = 0; reg_read(lanai, Status_Reg) & STATUS_BUTTBUSY; i++) {
-		if (unlikely(i > 50)) {
-			printk(KERN_ERR DEV_LABEL "(itf %d): butt register "
-			    "always busy!\n", lanai->number);
-			break;
-		}
-		udelay(5);
-	}
-	/*
-	 * Before we tall the card to start work we need to be sure 100% of
-	 * the info in the service buffer has been written before we tell
-	 * the card about it
-	 */
-	wmb();
-	reg_write(lanai, (ptr << 12) | lvcc->vci, Butt_Reg);
-	spin_unlock(&lanai->endtxlock);
-}
-
-/*
- * Add one AAL5 PDU to lvcc's transmit buffer.  Caller garauntees there's
- * space available.  "pdusize" is the number of bytes the PDU will take
- */
-static void lanai_send_one_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, struct sk_buff *skb, int pdusize)
-{
-	int pad;
-	APRINTK(pdusize == aal5_size(skb->len),
-	    "lanai_send_one_aal5: wrong size packet (%d != %d)\n",
-	    pdusize, aal5_size(skb->len));
-	vcc_tx_add_aal5_descriptor(lvcc, 0, pdusize);
-	pad = pdusize - skb->len - 8;
-	APRINTK(pad >= 0, "pad is negative (%d)\n", pad);
-	APRINTK(pad < 48, "pad is too big (%d)\n", pad);
-	vcc_tx_memcpy(lvcc, skb->data, skb->len);
-	vcc_tx_memzero(lvcc, pad);
-	vcc_tx_add_aal5_trailer(lvcc, skb->len, 0, 0);
-	lanai_endtx(lanai, lvcc);
-	lanai_free_skb(lvcc->tx.atmvcc, skb);
-	atomic_inc(&lvcc->tx.atmvcc->stats->tx);
-}
-
-/* Try to fill the buffer - don't call unless there is backlog */
-static void vcc_tx_unqueue_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, int endptr)
-{
-	int n;
-	struct sk_buff *skb;
-	int space = vcc_tx_space(lvcc, endptr);
-	APRINTK(vcc_is_backlogged(lvcc),
-	    "vcc_tx_unqueue() called with empty backlog (vci=%d)\n",
-	    lvcc->vci);
-	while (space >= 64) {
-		skb = skb_dequeue(&lvcc->tx.backlog);
-		if (skb == NULL)
-			goto no_backlog;
-		n = aal5_size(skb->len);
-		if (n + 16 > space) {
-			/* No room for this packet - put it back on queue */
-			skb_queue_head(&lvcc->tx.backlog, skb);
-			return;
-		}
-		lanai_send_one_aal5(lanai, lvcc, skb, n);
-		space -= n + 16;
-	}
-	if (!vcc_is_backlogged(lvcc)) {
-	    no_backlog:
-		__clear_bit(lvcc->vci, lanai->backlog_vccs);
-	}
-}
-
-/* Given an skb that we want to transmit either send it now or queue */
-static void vcc_tx_aal5(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	struct sk_buff *skb)
-{
-	int space, n;
-	if (vcc_is_backlogged(lvcc))		/* Already backlogged */
-		goto queue_it;
-	space = vcc_tx_space(lvcc,
-		    TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr)));
-	n = aal5_size(skb->len);
-	APRINTK(n + 16 >= 64, "vcc_tx_aal5: n too small (%d)\n", n);
-	if (space < n + 16) {			/* No space for this PDU */
-		__set_bit(lvcc->vci, lanai->backlog_vccs);
-	    queue_it:
-		skb_queue_tail(&lvcc->tx.backlog, skb);
-		return;
-	}
-	lanai_send_one_aal5(lanai, lvcc, skb, n);
-}
-
-static void vcc_tx_unqueue_aal0(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, int endptr)
-{
-	printk(KERN_INFO DEV_LABEL
-	    ": vcc_tx_unqueue_aal0: not implemented\n");
-}
-
-static void vcc_tx_aal0(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	struct sk_buff *skb)
-{
-	printk(KERN_INFO DEV_LABEL ": vcc_tx_aal0: not implemented\n");
-	/* Remember to increment lvcc->tx.atmvcc->stats->tx */
-	lanai_free_skb(lvcc->tx.atmvcc, skb);
-}
-
-/* -------------------- VCC RX BUFFER UTILITIES: */
-
-/* unlike the _tx_ cousins, this doesn't update ptr */
-static inline void vcc_rx_memcpy(unsigned char *dest,
-	const struct lanai_vcc *lvcc, int n)
-{
-	int m = ((const unsigned char *) lvcc->rx.buf.ptr) + n -
-	    ((const unsigned char *) (lvcc->rx.buf.end));
-	if (m < 0)
-		m = 0;
-	memcpy(dest, lvcc->rx.buf.ptr, n - m);
-	memcpy(dest + n - m, lvcc->rx.buf.start, m);
-	/* Make sure that these copies don't get reordered */
-	barrier();
-}
-
-/* Receive AAL5 data on a VCC with a particular endptr */
-static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
-{
-	int size;
-	struct sk_buff *skb;
-	const u32 *x;
-	u32 *end = &lvcc->rx.buf.start[endptr * 4];
-	int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr);
-	if (n < 0)
-		n += lanai_buf_size(&lvcc->rx.buf);
-	APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15),
-	    "vcc_rx_aal5: n out of range (%d/%zu)\n",
-	    n, lanai_buf_size(&lvcc->rx.buf));
-	/* Recover the second-to-last word to get true pdu length */
-	if ((x = &end[-2]) < lvcc->rx.buf.start)
-		x = &lvcc->rx.buf.end[-2];
-	/*
-	 * Before we actually read from the buffer, make sure the memory
-	 * changes have arrived
-	 */
-	rmb();
-	size = be32_to_cpup(x) & 0xffff;
-	if (unlikely(n != aal5_size(size))) {
-		/* Make sure size matches padding */
-		printk(KERN_INFO DEV_LABEL "(itf %d): Got bad AAL5 length "
-		    "on vci=%d - size=%d n=%d\n",
-		    lvcc->rx.atmvcc->dev->number, lvcc->vci, size, n);
-		lvcc->stats.x.aal5.rx_badlen++;
-		goto out;
-	}
-	skb = atm_alloc_charge(lvcc->rx.atmvcc, size, GFP_ATOMIC);
-	if (unlikely(skb == NULL)) {
-		lvcc->stats.rx_nomem++;
-		goto out;
-	}
-	skb_put(skb, size);
-	vcc_rx_memcpy(skb->data, lvcc, size);
-	ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
-	__net_timestamp(skb);
-	lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx);
-    out:
-	lvcc->rx.buf.ptr = end;
-	cardvcc_write(lvcc, endptr, vcc_rxreadptr);
-}
-
-static void vcc_rx_aal0(struct lanai_dev *lanai)
-{
-	printk(KERN_INFO DEV_LABEL ": vcc_rx_aal0: not implemented\n");
-	/* Remember to get read_lock(&vcc_sklist_lock) while looking up VC */
-	/* Remember to increment lvcc->rx.atmvcc->stats->rx */
-}
-
-/* -------------------- MANAGING HOST-BASED VCC TABLE: */
-
-/* Decide whether to use vmalloc or get_zeroed_page for VCC table */
-#if (NUM_VCI * BITS_PER_LONG) <= PAGE_SIZE
-#define VCCTABLE_GETFREEPAGE
-#else
-#include <linux/vmalloc.h>
-#endif
-
-static int vcc_table_allocate(struct lanai_dev *lanai)
-{
-#ifdef VCCTABLE_GETFREEPAGE
-	APRINTK((lanai->num_vci) * sizeof(struct lanai_vcc *) <= PAGE_SIZE,
-	    "vcc table > PAGE_SIZE!");
-	lanai->vccs = (struct lanai_vcc **) get_zeroed_page(GFP_KERNEL);
-	return (lanai->vccs == NULL) ? -ENOMEM : 0;
-#else
-	int bytes = (lanai->num_vci) * sizeof(struct lanai_vcc *);
-	lanai->vccs = vzalloc(bytes);
-	if (unlikely(lanai->vccs == NULL))
-		return -ENOMEM;
-	return 0;
-#endif
-}
-
-static inline void vcc_table_deallocate(const struct lanai_dev *lanai)
-{
-#ifdef VCCTABLE_GETFREEPAGE
-	free_page((unsigned long) lanai->vccs);
-#else
-	vfree(lanai->vccs);
-#endif
-}
-
-/* Allocate a fresh lanai_vcc, with the appropriate things cleared */
-static inline struct lanai_vcc *new_lanai_vcc(void)
-{
-	struct lanai_vcc *lvcc;
-	lvcc = kzalloc_obj(*lvcc);
-	if (likely(lvcc != NULL)) {
-		skb_queue_head_init(&lvcc->tx.backlog);
-#ifdef DEBUG
-		lvcc->vci = -1;
-#endif
-	}
-	return lvcc;
-}
-
-static int lanai_get_sized_buffer(struct lanai_dev *lanai,
-	struct lanai_buffer *buf, int max_sdu, int multiplier,
-	const char *name)
-{
-	int size;
-	if (unlikely(max_sdu < 1))
-		max_sdu = 1;
-	max_sdu = aal5_size(max_sdu);
-	size = (max_sdu + 16) * multiplier + 16;
-	lanai_buf_allocate(buf, size, max_sdu + 32, lanai->pci);
-	if (unlikely(buf->start == NULL))
-		return -ENOMEM;
-	if (unlikely(lanai_buf_size(buf) < size))
-		printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes "
-		    "for %s buffer, got only %zu\n", lanai->number, size,
-		    name, lanai_buf_size(buf));
-	DPRINTK("Allocated %zu byte %s buffer\n", lanai_buf_size(buf), name);
-	return 0;
-}
-
-/* Setup a RX buffer for a currently unbound AAL5 vci */
-static inline int lanai_setup_rx_vci_aal5(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, const struct atm_qos *qos)
-{
-	return lanai_get_sized_buffer(lanai, &lvcc->rx.buf,
-	    qos->rxtp.max_sdu, AAL5_RX_MULTIPLIER, "RX");
-}
-
-/* Setup a TX buffer for a currently unbound AAL5 vci */
-static int lanai_setup_tx_vci(struct lanai_dev *lanai, struct lanai_vcc *lvcc,
-	const struct atm_qos *qos)
-{
-	int max_sdu, multiplier;
-	if (qos->aal == ATM_AAL0) {
-		lvcc->tx.unqueue = vcc_tx_unqueue_aal0;
-		max_sdu = ATM_CELL_SIZE - 1;
-		multiplier = AAL0_TX_MULTIPLIER;
-	} else {
-		lvcc->tx.unqueue = vcc_tx_unqueue_aal5;
-		max_sdu = qos->txtp.max_sdu;
-		multiplier = AAL5_TX_MULTIPLIER;
-	}
-	return lanai_get_sized_buffer(lanai, &lvcc->tx.buf, max_sdu,
-	    multiplier, "TX");
-}
-
-static inline void host_vcc_bind(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc, vci_t vci)
-{
-	if (lvcc->vbase != NULL)
-		return;    /* We already were bound in the other direction */
-	DPRINTK("Binding vci %d\n", vci);
-#ifdef USE_POWERDOWN
-	if (lanai->nbound++ == 0) {
-		DPRINTK("Coming out of powerdown\n");
-		lanai->conf1 &= ~CONFIG1_POWERDOWN;
-		conf1_write(lanai);
-		conf2_write(lanai);
-	}
-#endif
-	lvcc->vbase = cardvcc_addr(lanai, vci);
-	lanai->vccs[lvcc->vci = vci] = lvcc;
-}
-
-static inline void host_vcc_unbind(struct lanai_dev *lanai,
-	struct lanai_vcc *lvcc)
-{
-	if (lvcc->vbase == NULL)
-		return;	/* This vcc was never bound */
-	DPRINTK("Unbinding vci %d\n", lvcc->vci);
-	lvcc->vbase = NULL;
-	lanai->vccs[lvcc->vci] = NULL;
-#ifdef USE_POWERDOWN
-	if (--lanai->nbound == 0) {
-		DPRINTK("Going into powerdown\n");
-		lanai->conf1 |= CONFIG1_POWERDOWN;
-		conf1_write(lanai);
-	}
-#endif
-}
-
-/* -------------------- RESET CARD: */
-
-static void lanai_reset(struct lanai_dev *lanai)
-{
-	printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not "
-	    "implemented\n", lanai->number);
-	/* TODO */
-	/* The following is just a hack until we write the real
-	 * resetter - at least ack whatever interrupt sent us
-	 * here
-	 */
-	reg_write(lanai, INT_ALL, IntAck_Reg);
-	lanai->stats.card_reset++;
-}
-
-/* -------------------- SERVICE LIST UTILITIES: */
-
-/*
- * Allocate service buffer and tell card about it
- */
-static int service_buffer_allocate(struct lanai_dev *lanai)
-{
-	lanai_buf_allocate(&lanai->service, SERVICE_ENTRIES * 4, 8,
-	    lanai->pci);
-	if (unlikely(lanai->service.start == NULL))
-		return -ENOMEM;
-	DPRINTK("allocated service buffer at %p, size %zu(%d)\n",
-	    lanai->service.start,
-	    lanai_buf_size(&lanai->service),
-	    lanai_buf_size_cardorder(&lanai->service));
-	/* Clear ServWrite register to be safe */
-	reg_write(lanai, 0, ServWrite_Reg);
-	/* ServiceStuff register contains size and address of buffer */
-	reg_write(lanai,
-	    SSTUFF_SET_SIZE(lanai_buf_size_cardorder(&lanai->service)) |
-	    SSTUFF_SET_ADDR(lanai->service.dmaaddr),
-	    ServiceStuff_Reg);
-	return 0;
-}
-
-static inline void service_buffer_deallocate(struct lanai_dev *lanai)
-{
-	lanai_buf_deallocate(&lanai->service, lanai->pci);
-}
-
-/* Bitfields in service list */
-#define SERVICE_TX	(0x80000000)	/* Was from transmission */
-#define SERVICE_TRASH	(0x40000000)	/* RXed PDU was trashed */
-#define SERVICE_CRCERR	(0x20000000)	/* RXed PDU had CRC error */
-#define SERVICE_CI	(0x10000000)	/* RXed PDU had CI set */
-#define SERVICE_CLP	(0x08000000)	/* RXed PDU had CLP set */
-#define SERVICE_STREAM	(0x04000000)	/* RX Stream mode */
-#define SERVICE_GET_VCI(x) (((x)>>16)&0x3FF)
-#define SERVICE_GET_END(x) ((x)&0x1FFF)
-
-/* Handle one thing from the service list - returns true if it marked a
- * VCC ready for xmit
- */
-static int handle_service(struct lanai_dev *lanai, u32 s)
-{
-	vci_t vci = SERVICE_GET_VCI(s);
-	struct lanai_vcc *lvcc;
-	read_lock(&vcc_sklist_lock);
-	lvcc = lanai->vccs[vci];
-	if (unlikely(lvcc == NULL)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got service entry 0x%X for nonexistent "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		if (s & SERVICE_TX)
-			lanai->stats.service_notx++;
-		else
-			lanai->stats.service_norx++;
-		return 0;
-	}
-	if (s & SERVICE_TX) {			/* segmentation interrupt */
-		if (unlikely(lvcc->tx.atmvcc == NULL)) {
-			read_unlock(&vcc_sklist_lock);
-			DPRINTK("(itf %d) got service entry 0x%X for non-TX "
-			    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-			lanai->stats.service_notx++;
-			return 0;
-		}
-		__set_bit(vci, lanai->transmit_ready);
-		lvcc->tx.endptr = SERVICE_GET_END(s);
-		read_unlock(&vcc_sklist_lock);
-		return 1;
-	}
-	if (unlikely(lvcc->rx.atmvcc == NULL)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got service entry 0x%X for non-RX "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		lanai->stats.service_norx++;
-		return 0;
-	}
-	if (unlikely(lvcc->rx.atmvcc->qos.aal != ATM_AAL5)) {
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("(itf %d) got RX service entry 0x%X for non-AAL5 "
-		    "vcc %d\n", lanai->number, (unsigned int) s, vci);
-		lanai->stats.service_rxnotaal5++;
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		return 0;
-	}
-	if (likely(!(s & (SERVICE_TRASH | SERVICE_STREAM | SERVICE_CRCERR)))) {
-		vcc_rx_aal5(lvcc, SERVICE_GET_END(s));
-		read_unlock(&vcc_sklist_lock);
-		return 0;
-	}
-	if (s & SERVICE_TRASH) {
-		int bytes;
-		read_unlock(&vcc_sklist_lock);
-		DPRINTK("got trashed rx pdu on vci %d\n", vci);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		lvcc->stats.x.aal5.service_trash++;
-		bytes = (SERVICE_GET_END(s) * 16) -
-		    (((unsigned long) lvcc->rx.buf.ptr) -
-		    ((unsigned long) lvcc->rx.buf.start)) + 47;
-		if (bytes < 0)
-			bytes += lanai_buf_size(&lvcc->rx.buf);
-		lanai->stats.ovfl_trash += (bytes / 48);
-		return 0;
-	}
-	if (s & SERVICE_STREAM) {
-		read_unlock(&vcc_sklist_lock);
-		atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-		lvcc->stats.x.aal5.service_stream++;
-		printk(KERN_ERR DEV_LABEL "(itf %d): Got AAL5 stream "
-		    "PDU on VCI %d!\n", lanai->number, vci);
-		lanai_reset(lanai);
-		return 0;
-	}
-	DPRINTK("got rx crc error on vci %d\n", vci);
-	atomic_inc(&lvcc->rx.atmvcc->stats->rx_err);
-	lvcc->stats.x.aal5.service_rxcrc++;
-	lvcc->rx.buf.ptr = &lvcc->rx.buf.start[SERVICE_GET_END(s) * 4];
-	cardvcc_write(lvcc, SERVICE_GET_END(s), vcc_rxreadptr);
-	read_unlock(&vcc_sklist_lock);
-	return 0;
-}
-
-/* Try transmitting on all VCIs that we marked ready to serve */
-static void iter_transmit(struct lanai_dev *lanai, vci_t vci)
-{
-	struct lanai_vcc *lvcc = lanai->vccs[vci];
-	if (vcc_is_backlogged(lvcc))
-		lvcc->tx.unqueue(lanai, lvcc, lvcc->tx.endptr);
-}
-
-/* Run service queue -- called from interrupt context or with
- * interrupts otherwise disabled and with the lanai->servicelock
- * lock held
- */
-static void run_service(struct lanai_dev *lanai)
-{
-	int ntx = 0;
-	u32 wreg = reg_read(lanai, ServWrite_Reg);
-	const u32 *end = lanai->service.start + wreg;
-	while (lanai->service.ptr != end) {
-		ntx += handle_service(lanai,
-		    le32_to_cpup(lanai->service.ptr++));
-		if (lanai->service.ptr >= lanai->service.end)
-			lanai->service.ptr = lanai->service.start;
-	}
-	reg_write(lanai, wreg, ServRead_Reg);
-	if (ntx != 0) {
-		read_lock(&vcc_sklist_lock);
-		vci_bitfield_iterate(lanai, lanai->transmit_ready,
-		    iter_transmit);
-		bitmap_zero(lanai->transmit_ready, NUM_VCI);
-		read_unlock(&vcc_sklist_lock);
-	}
-}
-
-/* -------------------- GATHER STATISTICS: */
-
-static void get_statistics(struct lanai_dev *lanai)
-{
-	u32 statreg = reg_read(lanai, Statistics_Reg);
-	lanai->stats.atm_ovfl += STATS_GET_FIFO_OVFL(statreg);
-	lanai->stats.hec_err += STATS_GET_HEC_ERR(statreg);
-	lanai->stats.vci_trash += STATS_GET_BAD_VCI(statreg);
-	lanai->stats.ovfl_trash += STATS_GET_BUF_OVFL(statreg);
-}
-
-/* -------------------- POLLING TIMER: */
-
-#ifndef DEBUG_RW
-/* Try to undequeue 1 backlogged vcc */
-static void iter_dequeue(struct lanai_dev *lanai, vci_t vci)
-{
-	struct lanai_vcc *lvcc = lanai->vccs[vci];
-	int endptr;
-	if (lvcc == NULL || lvcc->tx.atmvcc == NULL ||
-	    !vcc_is_backlogged(lvcc)) {
-		__clear_bit(vci, lanai->backlog_vccs);
-		return;
-	}
-	endptr = TXREADPTR_GET_PTR(cardvcc_read(lvcc, vcc_txreadptr));
-	lvcc->tx.unqueue(lanai, lvcc, endptr);
-}
-#endif /* !DEBUG_RW */
-
-static void lanai_timed_poll(struct timer_list *t)
-{
-	struct lanai_dev *lanai = timer_container_of(lanai, t, timer);
-#ifndef DEBUG_RW
-	unsigned long flags;
-#ifdef USE_POWERDOWN
-	if (lanai->conf1 & CONFIG1_POWERDOWN)
-		return;
-#endif /* USE_POWERDOWN */
-	local_irq_save(flags);
-	/* If we can grab the spinlock, check if any services need to be run */
-	if (spin_trylock(&lanai->servicelock)) {
-		run_service(lanai);
-		spin_unlock(&lanai->servicelock);
-	}
-	/* ...and see if any backlogged VCs can make progress */
-	/* unfortunately linux has no read_trylock() currently */
-	read_lock(&vcc_sklist_lock);
-	vci_bitfield_iterate(lanai, lanai->backlog_vccs, iter_dequeue);
-	read_unlock(&vcc_sklist_lock);
-	local_irq_restore(flags);
-
-	get_statistics(lanai);
-#endif /* !DEBUG_RW */
-	mod_timer(&lanai->timer, jiffies + LANAI_POLL_PERIOD);
-}
-
-static inline void lanai_timed_poll_start(struct lanai_dev *lanai)
-{
-	timer_setup(&lanai->timer, lanai_timed_poll, 0);
-	lanai->timer.expires = jiffies + LANAI_POLL_PERIOD;
-	add_timer(&lanai->timer);
-}
-
-static inline void lanai_timed_poll_stop(struct lanai_dev *lanai)
-{
-	timer_delete_sync(&lanai->timer);
-}
-
-/* -------------------- INTERRUPT SERVICE: */
-
-static inline void lanai_int_1(struct lanai_dev *lanai, u32 reason)
-{
-	u32 ack = 0;
-	if (reason & INT_SERVICE) {
-		ack = INT_SERVICE;
-		spin_lock(&lanai->servicelock);
-		run_service(lanai);
-		spin_unlock(&lanai->servicelock);
-	}
-	if (reason & (INT_AAL0_STR | INT_AAL0)) {
-		ack |= reason & (INT_AAL0_STR | INT_AAL0);
-		vcc_rx_aal0(lanai);
-	}
-	/* The rest of the interrupts are pretty rare */
-	if (ack == reason)
-		goto done;
-	if (reason & INT_STATS) {
-		reason &= ~INT_STATS;	/* No need to ack */
-		get_statistics(lanai);
-	}
-	if (reason & INT_STATUS) {
-		ack |= reason & INT_STATUS;
-		lanai_check_status(lanai);
-	}
-	if (unlikely(reason & INT_DMASHUT)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - DMA "
-		    "shutdown, reason=0x%08X, address=0x%08X\n",
-		    lanai->number, (unsigned int) (reason & INT_DMASHUT),
-		    (unsigned int) reg_read(lanai, DMA_Addr_Reg));
-		if (reason & INT_TABORTBM) {
-			lanai_reset(lanai);
-			return;
-		}
-		ack |= (reason & INT_DMASHUT);
-		printk(KERN_ERR DEV_LABEL "(itf %d): re-enabling DMA\n",
-		    lanai->number);
-		conf1_write(lanai);
-		lanai->stats.dma_reenable++;
-		pcistatus_check(lanai, 0);
-	}
-	if (unlikely(reason & INT_TABORTSENT)) {
-		ack |= (reason & INT_TABORTSENT);
-		printk(KERN_ERR DEV_LABEL "(itf %d): sent PCI target abort\n",
-		    lanai->number);
-		pcistatus_check(lanai, 0);
-	}
-	if (unlikely(reason & INT_SEGSHUT)) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
-		    "segmentation shutdown, reason=0x%08X\n", lanai->number,
-		    (unsigned int) (reason & INT_SEGSHUT));
-		lanai_reset(lanai);
-		return;
-	}
-	if (unlikely(reason & (INT_PING | INT_WAKE))) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): driver error - "
-		    "unexpected interrupt 0x%08X, resetting\n",
-		    lanai->number,
-		    (unsigned int) (reason & (INT_PING | INT_WAKE)));
-		lanai_reset(lanai);
-		return;
-	}
-#ifdef DEBUG
-	if (unlikely(ack != reason)) {
-		DPRINTK("unacked ints: 0x%08X\n",
-		    (unsigned int) (reason & ~ack));
-		ack = reason;
-	}
-#endif
-   done:
-	if (ack != 0)
-		reg_write(lanai, ack, IntAck_Reg);
-}
-
-static irqreturn_t lanai_int(int irq, void *devid)
-{
-	struct lanai_dev *lanai = devid;
-	u32 reason;
-
-#ifdef USE_POWERDOWN
-	/*
-	 * If we're powered down we shouldn't be generating any interrupts -
-	 * so assume that this is a shared interrupt line and it's for someone
-	 * else
-	 */
-	if (unlikely(lanai->conf1 & CONFIG1_POWERDOWN))
-		return IRQ_NONE;
-#endif
-
-	reason = intr_pending(lanai);
-	if (reason == 0)
-		return IRQ_NONE;	/* Must be for someone else */
-
-	do {
-		if (unlikely(reason == 0xFFFFFFFF))
-			break;		/* Maybe we've been unplugged? */
-		lanai_int_1(lanai, reason);
-		reason = intr_pending(lanai);
-	} while (reason != 0);
-
-	return IRQ_HANDLED;
-}
-
-/* TODO - it would be nice if we could use the "delayed interrupt" system
- *   to some advantage
- */
-
-/* -------------------- CHECK BOARD ID/REV: */
-
-/*
- * The board id and revision are stored both in the reset register and
- * in the PCI configuration space - the documentation says to check
- * each of them.  If revp!=NULL we store the revision there
- */
-static int check_board_id_and_rev(const char *name, u32 val, int *revp)
-{
-	DPRINTK("%s says board_id=%d, board_rev=%d\n", name,
-		(int) RESET_GET_BOARD_ID(val),
-		(int) RESET_GET_BOARD_REV(val));
-	if (RESET_GET_BOARD_ID(val) != BOARD_ID_LANAI256) {
-		printk(KERN_ERR DEV_LABEL ": Found %s board-id %d -- not a "
-		    "Lanai 25.6\n", name, (int) RESET_GET_BOARD_ID(val));
-		return -ENODEV;
-	}
-	if (revp != NULL)
-		*revp = RESET_GET_BOARD_REV(val);
-	return 0;
-}
-
-/* -------------------- PCI INITIALIZATION/SHUTDOWN: */
-
-static int lanai_pci_start(struct lanai_dev *lanai)
-{
-	struct pci_dev *pci = lanai->pci;
-	int result;
-
-	if (pci_enable_device(pci) != 0) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't enable "
-		    "PCI device", lanai->number);
-		return -ENXIO;
-	}
-	pci_set_master(pci);
-	if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32)) != 0) {
-		printk(KERN_WARNING DEV_LABEL
-		    "(itf %d): No suitable DMA available.\n", lanai->number);
-		return -EBUSY;
-	}
-	result = check_board_id_and_rev("PCI", pci->subsystem_device, NULL);
-	if (result != 0)
-		return result;
-	/* Set latency timer to zero as per lanai docs */
-	result = pci_write_config_byte(pci, PCI_LATENCY_TIMER, 0);
-	if (result != PCIBIOS_SUCCESSFUL) {
-		printk(KERN_ERR DEV_LABEL "(itf %d): can't write "
-		    "PCI_LATENCY_TIMER: %d\n", lanai->number, result);
-		return -EINVAL;
-	}
-	pcistatus_check(lanai, 1);
-	pcistatus_check(lanai, 0);
-	return 0;
-}
-
-/* -------------------- VPI/VCI ALLOCATION: */
-
-/*
- * We _can_ use VCI==0 for normal traffic, but only for UBR (or we'll
- * get a CBRZERO interrupt), and we can use it only if no one is receiving
- * AAL0 traffic (since they will use the same queue) - according to the
- * docs we shouldn't even use it for AAL0 traffic
- */
-static inline int vci0_is_ok(struct lanai_dev *lanai,
-	const struct atm_qos *qos)
-{
-	if (qos->txtp.traffic_class == ATM_CBR || qos->aal == ATM_AAL0)
-		return 0;
-	if (qos->rxtp.traffic_class != ATM_NONE) {
-		if (lanai->naal0 != 0)
-			return 0;
-		lanai->conf2 |= CONFIG2_VCI0_NORMAL;
-		conf2_write_if_powerup(lanai);
-	}
-	return 1;
-}
-
-/* return true if vci is currently unused, or if requested qos is
- * compatible
- */
-static int vci_is_ok(struct lanai_dev *lanai, vci_t vci,
-	const struct atm_vcc *atmvcc)
-{
-	const struct atm_qos *qos = &atmvcc->qos;
-	const struct lanai_vcc *lvcc = lanai->vccs[vci];
-	if (vci == 0 && !vci0_is_ok(lanai, qos))
-		return 0;
-	if (unlikely(lvcc != NULL)) {
-		if (qos->rxtp.traffic_class != ATM_NONE &&
-		    lvcc->rx.atmvcc != NULL && lvcc->rx.atmvcc != atmvcc)
-			return 0;
-		if (qos->txtp.traffic_class != ATM_NONE &&
-		    lvcc->tx.atmvcc != NULL && lvcc->tx.atmvcc != atmvcc)
-			return 0;
-		if (qos->txtp.traffic_class == ATM_CBR &&
-		    lanai->cbrvcc != NULL && lanai->cbrvcc != atmvcc)
-			return 0;
-	}
-	if (qos->aal == ATM_AAL0 && lanai->naal0 == 0 &&
-	    qos->rxtp.traffic_class != ATM_NONE) {
-		const struct lanai_vcc *vci0 = lanai->vccs[0];
-		if (vci0 != NULL && vci0->rx.atmvcc != NULL)
-			return 0;
-		lanai->conf2 &= ~CONFIG2_VCI0_NORMAL;
-		conf2_write_if_powerup(lanai);
-	}
-	return 1;
-}
-
-static int lanai_normalize_ci(struct lanai_dev *lanai,
-	const struct atm_vcc *atmvcc, short *vpip, vci_t *vcip)
-{
-	switch (*vpip) {
-		case ATM_VPI_ANY:
-			*vpip = 0;
-			fallthrough;
-		case 0:
-			break;
-		default:
-			return -EADDRINUSE;
-	}
-	switch (*vcip) {
-		case ATM_VCI_ANY:
-			for (*vcip = ATM_NOT_RSV_VCI; *vcip < lanai->num_vci;
-			    (*vcip)++)
-				if (vci_is_ok(lanai, *vcip, atmvcc))
-					return 0;
-			return -EADDRINUSE;
-		default:
-			if (*vcip >= lanai->num_vci || *vcip < 0 ||
-			    !vci_is_ok(lanai, *vcip, atmvcc))
-				return -EADDRINUSE;
-	}
-	return 0;
-}
-
-/* -------------------- MANAGE CBR: */
-
-/*
- * CBR ICG is stored as a fixed-point number with 4 fractional bits.
- * Note that storing a number greater than 2046.0 will result in
- * incorrect shaping
- */
-#define CBRICG_FRAC_BITS	(4)
-#define CBRICG_MAX		(2046 << CBRICG_FRAC_BITS)
-
-/*
- * ICG is related to PCR with the formula PCR = MAXPCR / (ICG + 1)
- * where MAXPCR is (according to the docs) 25600000/(54*8),
- * which is equal to (3125<<9)/27.
- *
- * Solving for ICG, we get:
- *    ICG = MAXPCR/PCR - 1
- *    ICG = (3125<<9)/(27*PCR) - 1
- *    ICG = ((3125<<9) - (27*PCR)) / (27*PCR)
- *
- * The end result is supposed to be a fixed-point number with FRAC_BITS
- * bits of a fractional part, so we keep everything in the numerator
- * shifted by that much as we compute
- *
- */
-static int pcr_to_cbricg(const struct atm_qos *qos)
-{
-	int rounddown = 0;	/* 1 = Round PCR down, i.e. round ICG _up_ */
-	int x, icg, pcr = atm_pcr_goal(&qos->txtp);
-	if (pcr == 0)		/* Use maximum bandwidth */
-		return 0;
-	if (pcr < 0) {
-		rounddown = 1;
-		pcr = -pcr;
-	}
-	x = pcr * 27;
-	icg = (3125 << (9 + CBRICG_FRAC_BITS)) - (x << CBRICG_FRAC_BITS);
-	if (rounddown)
-		icg += x - 1;
-	icg /= x;
-	if (icg > CBRICG_MAX)
-		icg = CBRICG_MAX;
-	DPRINTK("pcr_to_cbricg: pcr=%d rounddown=%c icg=%d\n",
-	    pcr, rounddown ? 'Y' : 'N', icg);
-	return icg;
-}
-
-static inline void lanai_cbr_setup(struct lanai_dev *lanai)
-{
-	reg_write(lanai, pcr_to_cbricg(&lanai->cbrvcc->qos), CBR_ICG_Reg);
-	reg_write(lanai, lanai->cbrvcc->vci, CBR_PTR_Reg);
-	lanai->conf2 |= CONFIG2_CBR_ENABLE;
-	conf2_write(lanai);
-}
-
-static inline void lanai_cbr_shutdown(struct lanai_dev *lanai)
-{
-	lanai->conf2 &= ~CONFIG2_CBR_ENABLE;
-	conf2_write(lanai);
-}
-
-/* -------------------- OPERATIONS: */
-
-/* setup a newly detected device */
-static int lanai_dev_open(struct atm_dev *atmdev)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	unsigned long raw_base;
-	int result;
-
-	DPRINTK("In lanai_dev_open()\n");
-	/* Basic device fields */
-	lanai->number = atmdev->number;
-	lanai->num_vci = NUM_VCI;
-	bitmap_zero(lanai->backlog_vccs, NUM_VCI);
-	bitmap_zero(lanai->transmit_ready, NUM_VCI);
-	lanai->naal0 = 0;
-#ifdef USE_POWERDOWN
-	lanai->nbound = 0;
-#endif
-	lanai->cbrvcc = NULL;
-	memset(&lanai->stats, 0, sizeof lanai->stats);
-	spin_lock_init(&lanai->endtxlock);
-	spin_lock_init(&lanai->servicelock);
-	atmdev->ci_range.vpi_bits = 0;
-	atmdev->ci_range.vci_bits = 0;
-	while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)
-		atmdev->ci_range.vci_bits++;
-	atmdev->link_rate = ATM_25_PCR;
-
-	/* 3.2: PCI initialization */
-	if ((result = lanai_pci_start(lanai)) != 0)
-		goto error;
-	raw_base = lanai->pci->resource[0].start;
-	lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
-	if (lanai->base == NULL) {
-		printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
-		result = -ENOMEM;
-		goto error_pci;
-	}
-	/* 3.3: Reset lanai and PHY */
-	reset_board(lanai);
-	lanai->conf1 = reg_read(lanai, Config1_Reg);
-	lanai->conf1 &= ~(CONFIG1_GPOUT1 | CONFIG1_POWERDOWN |
-	    CONFIG1_MASK_LEDMODE);
-	lanai->conf1 |= CONFIG1_SET_LEDMODE(LEDMODE_NOT_SOOL);
-	reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
-	udelay(1000);
-	conf1_write(lanai);
-
-	/*
-	 * 3.4: Turn on endian mode for big-endian hardware
-	 *   We don't actually want to do this - the actual bit fields
-	 *   in the endian register are not documented anywhere.
-	 *   Instead we do the bit-flipping ourselves on big-endian
-	 *   hardware.
-	 *
-	 * 3.5: get the board ID/rev by reading the reset register
-	 */
-	result = check_board_id_and_rev("register",
-	    reg_read(lanai, Reset_Reg), &lanai->board_rev);
-	if (result != 0)
-		goto error_unmap;
-
-	/* 3.6: read EEPROM */
-	if ((result = eeprom_read(lanai)) != 0)
-		goto error_unmap;
-	if ((result = eeprom_validate(lanai)) != 0)
-		goto error_unmap;
-
-	/* 3.7: re-reset PHY, do loopback tests, setup PHY */
-	reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
-	udelay(1000);
-	conf1_write(lanai);
-	/* TODO - loopback tests */
-	lanai->conf1 |= (CONFIG1_GPOUT2 | CONFIG1_GPOUT3 | CONFIG1_DMA_ENABLE);
-	conf1_write(lanai);
-
-	/* 3.8/3.9: test and initialize card SRAM */
-	if ((result = sram_test_and_clear(lanai)) != 0)
-		goto error_unmap;
-
-	/* 3.10: initialize lanai registers */
-	lanai->conf1 |= CONFIG1_DMA_ENABLE;
-	conf1_write(lanai);
-	if ((result = service_buffer_allocate(lanai)) != 0)
-		goto error_unmap;
-	if ((result = vcc_table_allocate(lanai)) != 0)
-		goto error_service;
-	lanai->conf2 = (lanai->num_vci >= 512 ? CONFIG2_HOWMANY : 0) |
-	    CONFIG2_HEC_DROP |	/* ??? */ CONFIG2_PTI7_MODE;
-	conf2_write(lanai);
-	reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);
-	reg_write(lanai, 0, CBR_ICG_Reg);	/* CBR defaults to no limit */
-	if ((result = request_irq(lanai->pci->irq, lanai_int, IRQF_SHARED,
-	    DEV_LABEL, lanai)) != 0) {
-		printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
-		goto error_vcctable;
-	}
-	mb();				/* Make sure that all that made it */
-	intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
-	/* 3.11: initialize loop mode (i.e. turn looping off) */
-	lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |
-	    CONFIG1_SET_LOOPMODE(LOOPMODE_NORMAL) |
-	    CONFIG1_GPOUT2 | CONFIG1_GPOUT3;
-	conf1_write(lanai);
-	lanai->status = reg_read(lanai, Status_Reg);
-	/* We're now done initializing this card */
-#ifdef USE_POWERDOWN
-	lanai->conf1 |= CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);
-	lanai_timed_poll_start(lanai);
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=%p, irq=%u "
-		"(%pMF)\n", lanai->number, (int) lanai->pci->revision,
-		lanai->base, lanai->pci->irq, atmdev->esi);
-	printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), "
-	    "board_rev=%d\n", lanai->number,
-	    lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno,
-	    (unsigned int) lanai->serialno, lanai->board_rev);
-	return 0;
-
-    error_vcctable:
-	vcc_table_deallocate(lanai);
-    error_service:
-	service_buffer_deallocate(lanai);
-    error_unmap:
-	reset_board(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 = reg_read(lanai, Config1_Reg) | CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	iounmap(lanai->base);
-	lanai->base = NULL;
-    error_pci:
-	pci_disable_device(lanai->pci);
-    error:
-	return result;
-}
-
-/* called when device is being shutdown, and all vcc's are gone - higher
- * levels will deallocate the atm device for us
- */
-static void lanai_dev_close(struct atm_dev *atmdev)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	if (lanai->base==NULL)
-		return;
-	printk(KERN_INFO DEV_LABEL "(itf %d): shutting down interface\n",
-	    lanai->number);
-	lanai_timed_poll_stop(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 = reg_read(lanai, Config1_Reg) & ~CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	intr_disable(lanai, INT_ALL);
-	free_irq(lanai->pci->irq, lanai);
-	reset_board(lanai);
-#ifdef USE_POWERDOWN
-	lanai->conf1 |= CONFIG1_POWERDOWN;
-	conf1_write(lanai);
-#endif
-	pci_disable_device(lanai->pci);
-	vcc_table_deallocate(lanai);
-	service_buffer_deallocate(lanai);
-	iounmap(lanai->base);
-	kfree(lanai);
-}
-
-/* close a vcc */
-static void lanai_close(struct atm_vcc *atmvcc)
-{
-	struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
-	struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	if (lvcc == NULL)
-		return;
-	clear_bit(ATM_VF_READY, &atmvcc->flags);
-	clear_bit(ATM_VF_PARTIAL, &atmvcc->flags);
-	if (lvcc->rx.atmvcc == atmvcc) {
-		lanai_shutdown_rx_vci(lvcc);
-		if (atmvcc->qos.aal == ATM_AAL0) {
-			if (--lanai->naal0 <= 0)
-				aal0_buffer_free(lanai);
-		} else
-			lanai_buf_deallocate(&lvcc->rx.buf, lanai->pci);
-		lvcc->rx.atmvcc = NULL;
-	}
-	if (lvcc->tx.atmvcc == atmvcc) {
-		if (atmvcc == lanai->cbrvcc) {
-			if (lvcc->vbase != NULL)
-				lanai_cbr_shutdown(lanai);
-			lanai->cbrvcc = NULL;
-		}
-		lanai_shutdown_tx_vci(lanai, lvcc);
-		lanai_buf_deallocate(&lvcc->tx.buf, lanai->pci);
-		lvcc->tx.atmvcc = NULL;
-	}
-	if (--lvcc->nref == 0) {
-		host_vcc_unbind(lanai, lvcc);
-		kfree(lvcc);
-	}
-	atmvcc->dev_data = NULL;
-	clear_bit(ATM_VF_ADDR, &atmvcc->flags);
-}
-
-/* open a vcc on the card to vpi/vci */
-static int lanai_open(struct atm_vcc *atmvcc)
-{
-	struct lanai_dev *lanai;
-	struct lanai_vcc *lvcc;
-	int result = 0;
-	int vci = atmvcc->vci;
-	short vpi = atmvcc->vpi;
-	/* we don't support partial open - it's not really useful anyway */
-	if ((test_bit(ATM_VF_PARTIAL, &atmvcc->flags)) ||
-	    (vpi == ATM_VPI_UNSPEC) || (vci == ATM_VCI_UNSPEC))
-		return -EINVAL;
-	lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	result = lanai_normalize_ci(lanai, atmvcc, &vpi, &vci);
-	if (unlikely(result != 0))
-		goto out;
-	set_bit(ATM_VF_ADDR, &atmvcc->flags);
-	if (atmvcc->qos.aal != ATM_AAL0 && atmvcc->qos.aal != ATM_AAL5)
-		return -EINVAL;
-	DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n", lanai->number,
-	    (int) vpi, vci);
-	lvcc = lanai->vccs[vci];
-	if (lvcc == NULL) {
-		lvcc = new_lanai_vcc();
-		if (unlikely(lvcc == NULL))
-			return -ENOMEM;
-		atmvcc->dev_data = lvcc;
-	}
-	lvcc->nref++;
-	if (atmvcc->qos.rxtp.traffic_class != ATM_NONE) {
-		APRINTK(lvcc->rx.atmvcc == NULL, "rx.atmvcc!=NULL, vci=%d\n",
-		    vci);
-		if (atmvcc->qos.aal == ATM_AAL0) {
-			if (lanai->naal0 == 0)
-				result = aal0_buffer_allocate(lanai);
-		} else
-			result = lanai_setup_rx_vci_aal5(
-			    lanai, lvcc, &atmvcc->qos);
-		if (unlikely(result != 0))
-			goto out_free;
-		lvcc->rx.atmvcc = atmvcc;
-		lvcc->stats.rx_nomem = 0;
-		lvcc->stats.x.aal5.rx_badlen = 0;
-		lvcc->stats.x.aal5.service_trash = 0;
-		lvcc->stats.x.aal5.service_stream = 0;
-		lvcc->stats.x.aal5.service_rxcrc = 0;
-		if (atmvcc->qos.aal == ATM_AAL0)
-			lanai->naal0++;
-	}
-	if (atmvcc->qos.txtp.traffic_class != ATM_NONE) {
-		APRINTK(lvcc->tx.atmvcc == NULL, "tx.atmvcc!=NULL, vci=%d\n",
-		    vci);
-		result = lanai_setup_tx_vci(lanai, lvcc, &atmvcc->qos);
-		if (unlikely(result != 0))
-			goto out_free;
-		lvcc->tx.atmvcc = atmvcc;
-		if (atmvcc->qos.txtp.traffic_class == ATM_CBR) {
-			APRINTK(lanai->cbrvcc == NULL,
-			    "cbrvcc!=NULL, vci=%d\n", vci);
-			lanai->cbrvcc = atmvcc;
-		}
-	}
-	host_vcc_bind(lanai, lvcc, vci);
-	/*
-	 * Make sure everything made it to RAM before we tell the card about
-	 * the VCC
-	 */
-	wmb();
-	if (atmvcc == lvcc->rx.atmvcc)
-		host_vcc_start_rx(lvcc);
-	if (atmvcc == lvcc->tx.atmvcc) {
-		host_vcc_start_tx(lvcc);
-		if (lanai->cbrvcc == atmvcc)
-			lanai_cbr_setup(lanai);
-	}
-	set_bit(ATM_VF_READY, &atmvcc->flags);
-	return 0;
-    out_free:
-	lanai_close(atmvcc);
-    out:
-	return result;
-}
-
-static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb)
-{
-	struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data;
-	struct lanai_dev *lanai = (struct lanai_dev *) atmvcc->dev->dev_data;
-	unsigned long flags;
-	if (unlikely(lvcc == NULL || lvcc->vbase == NULL ||
-	      lvcc->tx.atmvcc != atmvcc))
-		goto einval;
-#ifdef DEBUG
-	if (unlikely(skb == NULL)) {
-		DPRINTK("lanai_send: skb==NULL for vci=%d\n", atmvcc->vci);
-		goto einval;
-	}
-	if (unlikely(lanai == NULL)) {
-		DPRINTK("lanai_send: lanai==NULL for vci=%d\n", atmvcc->vci);
-		goto einval;
-	}
-#endif
-	ATM_SKB(skb)->vcc = atmvcc;
-	switch (atmvcc->qos.aal) {
-		case ATM_AAL5:
-			read_lock_irqsave(&vcc_sklist_lock, flags);
-			vcc_tx_aal5(lanai, lvcc, skb);
-			read_unlock_irqrestore(&vcc_sklist_lock, flags);
-			return 0;
-		case ATM_AAL0:
-			if (unlikely(skb->len != ATM_CELL_SIZE-1))
-				goto einval;
-  /* NOTE - this next line is technically invalid - we haven't unshared skb */
-			cpu_to_be32s((u32 *) skb->data);
-			read_lock_irqsave(&vcc_sklist_lock, flags);
-			vcc_tx_aal0(lanai, lvcc, skb);
-			read_unlock_irqrestore(&vcc_sklist_lock, flags);
-			return 0;
-	}
-	DPRINTK("lanai_send: bad aal=%d on vci=%d\n", (int) atmvcc->qos.aal,
-	    atmvcc->vci);
-    einval:
-	lanai_free_skb(atmvcc, skb);
-	return -EINVAL;
-}
-
-static int lanai_change_qos(struct atm_vcc *atmvcc,
-	/*const*/ struct atm_qos *qos, int flags)
-{
-	return -EBUSY;		/* TODO: need to write this */
-}
-
-#ifndef CONFIG_PROC_FS
-#define lanai_proc_read NULL
-#else
-static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page)
-{
-	struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
-	loff_t left = *pos;
-	struct lanai_vcc *lvcc;
-	if (left-- == 0)
-		return sprintf(page, DEV_LABEL "(itf %d): chip=LANAI%s, "
-		    "serial=%u, magic=0x%08X, num_vci=%d\n",
-		    atmdev->number, lanai->type==lanai2 ? "2" : "HB",
-		    (unsigned int) lanai->serialno,
-		    (unsigned int) lanai->magicno, lanai->num_vci);
-	if (left-- == 0)
-		return sprintf(page, "revision: board=%d, pci_if=%d\n",
-		    lanai->board_rev, (int) lanai->pci->revision);
-	if (left-- == 0)
-		return sprintf(page, "EEPROM ESI: %pM\n",
-		    &lanai->eeprom[EEPROM_MAC]);
-	if (left-- == 0)
-		return sprintf(page, "status: SOOL=%d, LOCD=%d, LED=%d, "
-		    "GPIN=%d\n", (lanai->status & STATUS_SOOL) ? 1 : 0,
-		    (lanai->status & STATUS_LOCD) ? 1 : 0,
-		    (lanai->status & STATUS_LED) ? 1 : 0,
-		    (lanai->status & STATUS_GPIN) ? 1 : 0);
-	if (left-- == 0)
-		return sprintf(page, "global buffer sizes: service=%zu, "
-		    "aal0_rx=%zu\n", lanai_buf_size(&lanai->service),
-		    lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0);
-	if (left-- == 0) {
-		get_statistics(lanai);
-		return sprintf(page, "cells in error: overflow=%u, "
-		    "closed_vci=%u, bad_HEC=%u, rx_fifo=%u\n",
-		    lanai->stats.ovfl_trash, lanai->stats.vci_trash,
-		    lanai->stats.hec_err, lanai->stats.atm_ovfl);
-	}
-	if (left-- == 0)
-		return sprintf(page, "PCI errors: parity_detect=%u, "
-		    "master_abort=%u, master_target_abort=%u,\n",
-		    lanai->stats.pcierr_parity_detect,
-		    lanai->stats.pcierr_serr_set,
-		    lanai->stats.pcierr_m_target_abort);
-	if (left-- == 0)
-		return sprintf(page, "            slave_target_abort=%u, "
-		    "master_parity=%u\n", lanai->stats.pcierr_s_target_abort,
-		    lanai->stats.pcierr_master_parity);
-	if (left-- == 0)
-		return sprintf(page, "                     no_tx=%u, "
-		    "no_rx=%u, bad_rx_aal=%u\n", lanai->stats.service_norx,
-		    lanai->stats.service_notx,
-		    lanai->stats.service_rxnotaal5);
-	if (left-- == 0)
-		return sprintf(page, "resets: dma=%u, card=%u\n",
-		    lanai->stats.dma_reenable, lanai->stats.card_reset);
-	/* At this point, "left" should be the VCI we're looking for */
-	read_lock(&vcc_sklist_lock);
-	for (; ; left++) {
-		if (left >= NUM_VCI) {
-			left = 0;
-			goto out;
-		}
-		if ((lvcc = lanai->vccs[left]) != NULL)
-			break;
-		(*pos)++;
-	}
-	/* Note that we re-use "left" here since we're done with it */
-	left = sprintf(page, "VCI %4d: nref=%d, rx_nomem=%u",  (vci_t) left,
-	    lvcc->nref, lvcc->stats.rx_nomem);
-	if (lvcc->rx.atmvcc != NULL) {
-		left += sprintf(&page[left], ",\n          rx_AAL=%d",
-		    lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0);
-		if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5)
-			left += sprintf(&page[left], ", rx_buf_size=%zu, "
-			    "rx_bad_len=%u,\n          rx_service_trash=%u, "
-			    "rx_service_stream=%u, rx_bad_crc=%u",
-			    lanai_buf_size(&lvcc->rx.buf),
-			    lvcc->stats.x.aal5.rx_badlen,
-			    lvcc->stats.x.aal5.service_trash,
-			    lvcc->stats.x.aal5.service_stream,
-			    lvcc->stats.x.aal5.service_rxcrc);
-	}
-	if (lvcc->tx.atmvcc != NULL)
-		left += sprintf(&page[left], ",\n          tx_AAL=%d, "
-		    "tx_buf_size=%zu, tx_qos=%cBR, tx_backlogged=%c",
-		    lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0,
-		    lanai_buf_size(&lvcc->tx.buf),
-		    lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U',
-		    vcc_is_backlogged(lvcc) ? 'Y' : 'N');
-	page[left++] = '\n';
-	page[left] = '\0';
-    out:
-	read_unlock(&vcc_sklist_lock);
-	return left;
-}
-#endif /* CONFIG_PROC_FS */
-
-/* -------------------- HOOKS: */
-
-static const struct atmdev_ops ops = {
-	.dev_close	= lanai_dev_close,
-	.open		= lanai_open,
-	.close		= lanai_close,
-	.send		= lanai_send,
-	.phy_put	= NULL,
-	.phy_get	= NULL,
-	.change_qos	= lanai_change_qos,
-	.proc_read	= lanai_proc_read,
-	.owner		= THIS_MODULE
-};
-
-/* initialize one probed card */
-static int lanai_init_one(struct pci_dev *pci,
-			  const struct pci_device_id *ident)
-{
-	struct lanai_dev *lanai;
-	struct atm_dev *atmdev;
-	int result;
-
-	lanai = kzalloc_obj(*lanai);
-	if (lanai == NULL) {
-		printk(KERN_ERR DEV_LABEL
-		       ": couldn't allocate dev_data structure!\n");
-		return -ENOMEM;
-	}
-
-	atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL);
-	if (atmdev == NULL) {
-		printk(KERN_ERR DEV_LABEL
-		    ": couldn't register atm device!\n");
-		kfree(lanai);
-		return -EBUSY;
-	}
-
-	atmdev->dev_data = lanai;
-	lanai->pci = pci;
-	lanai->type = (enum lanai_type) ident->device;
-
-	result = lanai_dev_open(atmdev);
-	if (result != 0) {
-		DPRINTK("lanai_start() failed, err=%d\n", -result);
-		atm_dev_deregister(atmdev);
-		kfree(lanai);
-	}
-	return result;
-}
-
-static const struct pci_device_id lanai_pci_tbl[] = {
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAI2) },
-	{ PCI_VDEVICE(EF, PCI_DEVICE_ID_EF_ATM_LANAIHB) },
-	{ 0, }	/* terminal entry */
-};
-MODULE_DEVICE_TABLE(pci, lanai_pci_tbl);
-
-static struct pci_driver lanai_driver = {
-	.name     = DEV_LABEL,
-	.id_table = lanai_pci_tbl,
-	.probe    = lanai_init_one,
-};
-
-module_pci_driver(lanai_driver);
-
-MODULE_AUTHOR("Mitchell Blank Jr <mitch@sfgoth.com>");
-MODULE_DESCRIPTION("Efficient Networks Speedstream 3010 driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/midway.h b/drivers/atm/midway.h
deleted file mode 100644
index d47307a..0000000
--- a/drivers/atm/midway.h
+++ /dev/null
@@ -1,266 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/midway.h - Efficient Networks Midway (SAR) description */
- 
-/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
- 
-
-#ifndef DRIVERS_ATM_MIDWAY_H
-#define DRIVERS_ATM_MIDWAY_H
-
-
-#define NR_VCI		1024		/* number of VCIs */
-#define NR_VCI_LD	10		/* log2(NR_VCI) */
-#define NR_DMA_RX	512		/* RX DMA queue entries */
-#define NR_DMA_TX	512		/* TX DMA queue entries */
-#define NR_SERVICE	NR_VCI		/* service list size */
-#define NR_CHAN		8		/* number of TX channels */
-#define TS_CLOCK	25000000	/* traffic shaper clock (cell/sec) */
-
-#define MAP_MAX_SIZE	0x00400000	/* memory window for max config */
-#define EPROM_SIZE	0x00010000
-#define	MEM_VALID	0xffc00000	/* mask base address with this */
-#define PHY_BASE	0x00020000	/* offset of PHY register are */
-#define REG_BASE	0x00040000	/* offset of Midway register area */
-#define RAM_BASE	0x00200000	/* offset of RAM area */
-#define RAM_INCREMENT	0x00020000	/* probe for RAM every 128kB */
-
-#define MID_VCI_BASE	RAM_BASE
-#define MID_DMA_RX_BASE	(MID_VCI_BASE+NR_VCI*16)
-#define MID_DMA_TX_BASE	(MID_DMA_RX_BASE+NR_DMA_RX*8)
-#define MID_SERVICE_BASE (MID_DMA_TX_BASE+NR_DMA_TX*8)
-#define MID_FREE_BASE	(MID_SERVICE_BASE+NR_SERVICE*4)
-
-#define MAC_LEN 6 /* atm.h */
-
-#define MID_MIN_BUF_SIZE (1024)		/*   1 kB is minimum */
-#define MID_MAX_BUF_SIZE (128*1024)	/* 128 kB is maximum */
-
-#define RX_DESCR_SIZE	1		/* RX PDU descr is 1 longword */
-#define TX_DESCR_SIZE	2		/* TX PDU descr is 2 longwords */
-#define AAL5_TRAILER	(ATM_AAL5_TRAILER/4) /* AAL5 trailer is 2 longwords */
-
-#define TX_GAP		8		/* TX buffer gap (words) */
-
-/*
- * Midway Reset/ID
- *
- * All values read-only. Writing to this register resets Midway chip.
- */
-
-#define MID_RES_ID_MCON	0x00		/* Midway Reset/ID */
-
-#define MID_ID		0xf0000000	/* Midway version */
-#define MID_SHIFT	24
-#define MID_MOTHER_ID	0x00000700	/* mother board id */
-#define MID_MOTHER_SHIFT 8
-#define MID_CON_TI	0x00000080	/* 0: normal ctrl; 1: SABRE */
-#define MID_CON_SUNI	0x00000040	/* 0: UTOPIA; 1: SUNI */
-#define MID_CON_V6	0x00000020	/* 0: non-pipel UTOPIA (required iff
-					   !CON_SUNI; 1: UTOPIA */
-#define DAUGHTER_ID	0x0000001f	/* daughter board id */
-
-/*
- * Interrupt Status Acknowledge, Interrupt Status & Interrupt Enable
- */
-
-#define MID_ISA		0x01		/* Interrupt Status Acknowledge */
-#define MID_IS		0x02		/* Interrupt Status */
-#define MID_IE		0x03		/* Interrupt Enable */
-
-#define MID_TX_COMPLETE_7 0x00010000	/* channel N completed a PDU */
-#define MID_TX_COMPLETE_6 0x00008000	/* transmission */
-#define MID_TX_COMPLETE_5 0x00004000
-#define MID_TX_COMPLETE_4 0x00002000
-#define MID_TX_COMPLETE_3 0x00001000
-#define MID_TX_COMPLETE_2 0x00000800
-#define MID_TX_COMPLETE_1 0x00000400
-#define MID_TX_COMPLETE_0 0x00000200
-#define MID_TX_COMPLETE	0x0001fe00	/* any TX */
-#define MID_TX_DMA_OVFL	0x00000100	/* DMA to adapter overflow */
-#define MID_TX_IDENT_MISM 0x00000080	/* TX: ident mismatch => halted */
-#define MID_DMA_LERR_ACK 0x00000040	/* LERR - SBus ? */
-#define MID_DMA_ERR_ACK	0x00000020	/* DMA error */
-#define	MID_RX_DMA_COMPLETE 0x00000010	/* DMA to host done */
-#define MID_TX_DMA_COMPLETE 0x00000008	/* DMA from host done */
-#define MID_SERVICE	0x00000004	/* something in service list */
-#define MID_SUNI_INT	0x00000002	/* interrupt from SUNI */
-#define MID_STAT_OVFL	0x00000001	/* statistics overflow */
-
-/*
- * Master Control/Status
- */
-
-#define MID_MC_S	0x04
-
-#define MID_INT_SELECT	0x000001C0	/* Interrupt level (000: off) */
-#define MID_INT_SEL_SHIFT 6
-#define	MID_TX_LOCK_MODE 0x00000020	/* 0: streaming; 1: TX ovfl->lock */
-#define MID_DMA_ENABLE	0x00000010	/* R: 0: disable; 1: enable
-					   W: 0: no change; 1: enable */
-#define MID_TX_ENABLE	0x00000008	/* R: 0: TX disabled; 1: enabled
-					   W: 0: no change; 1: enable */
-#define MID_RX_ENABLE	0x00000004	/* like TX */
-#define MID_WAIT_1MS	0x00000002	/* R: 0: timer not running; 1: running
-					   W: 0: no change; 1: no interrupts
-							       for 1 ms */
-#define MID_WAIT_500US	0x00000001	/* like WAIT_1MS, but 0.5 ms */
-
-/*
- * Statistics
- *
- * Cleared when reading.
- */
-
-#define MID_STAT		0x05
-
-#define MID_VCI_TRASH	0xFFFF0000	/* trashed cells because of VCI mode */
-#define MID_VCI_TRASH_SHIFT 16
-#define MID_OVFL_TRASH	0x0000FFFF	/* trashed cells because of overflow */
-
-/*
- * Address registers
- */
-
-#define MID_SERV_WRITE	0x06	/* free pos in service area (R, 10 bits) */
-#define MID_DMA_ADDR	0x07	/* virtual DMA address (R, 32 bits) */
-#define MID_DMA_WR_RX	0x08	/* (RW, 9 bits) */
-#define MID_DMA_RD_RX	0x09
-#define MID_DMA_WR_TX	0x0A
-#define MID_DMA_RD_TX	0x0B
-
-/*
- * Transmit Place Registers (0x10+4*channel)
- */
-
-#define MID_TX_PLACE(c)	(0x10+4*(c))
-
-#define MID_SIZE	0x00003800	/* size, N*256 x 32 bit */
-#define MID_SIZE_SHIFT	11
-#define MID_LOCATION	0x000007FF	/* location in adapter memory (word) */
-
-#define MID_LOC_SKIP	8		/* 8 bits of location are always zero
-					   (applies to all uses of location) */
-
-/*
- * Transmit ReadPtr Registers (0x11+4*channel)
- */
-
-#define MID_TX_RDPTR(c)	(0x11+4*(c))
-
-#define MID_READ_PTR	0x00007FFF	/* next word for PHY */
-
-/*
- * Transmit DescrStart Registers (0x12+4*channel)
- */
-
-#define MID_TX_DESCRSTART(c) (0x12+4*(c))
-
-#define MID_DESCR_START	0x00007FFF	/* seg buffer being DMAed */
-
-#define ENI155_MAGIC	0xa54b872d
-
-struct midway_eprom {
-	unsigned char mac[MAC_LEN],inv_mac[MAC_LEN];
-	unsigned char pad[36];
-	u32 serial,inv_serial;
-	u32 magic,inv_magic;
-};
-
-
-/*
- * VCI table entry
- */
-
-#define MID_VCI_IN_SERVICE	0x00000001	/* set if VCI is currently in
-						   service list */
-#define MID_VCI_SIZE		0x00038000	/* reassembly buffer size,
-						   2*<size> kB */
-#define MID_VCI_SIZE_SHIFT	15
-#define MID_VCI_LOCATION	0x1ffc0000	/* buffer location */
-#define MID_VCI_LOCATION_SHIFT	18
-#define MID_VCI_PTI_MODE	0x20000000	/* 0: trash, 1: preserve */
-#define MID_VCI_MODE		0xc0000000
-#define MID_VCI_MODE_SHIFT	30
-#define MID_VCI_READ		0x00007fff
-#define MID_VCI_READ_SHIFT	0
-#define MID_VCI_DESCR		0x7fff0000
-#define MID_VCI_DESCR_SHIFT	16
-#define MID_VCI_COUNT		0x000007ff
-#define MID_VCI_COUNT_SHIFT	0
-#define MID_VCI_STATE		0x0000c000
-#define MID_VCI_STATE_SHIFT	14
-#define MID_VCI_WRITE		0x7fff0000
-#define MID_VCI_WRITE_SHIFT	16
-
-#define MID_MODE_TRASH	0
-#define MID_MODE_RAW	1
-#define MID_MODE_AAL5	2
-
-/*
- * Reassembly buffer descriptor
- */
-
-#define MID_RED_COUNT		0x000007ff
-#define MID_RED_CRC_ERR		0x00000800
-#define MID_RED_T		0x00001000
-#define MID_RED_CE		0x00010000
-#define MID_RED_CLP		0x01000000
-#define MID_RED_IDEN		0xfe000000
-#define MID_RED_SHIFT		25
-
-#define MID_RED_RX_ID		0x1b		/* constant identifier */
-
-/*
- * Segmentation buffer descriptor
- */
-
-#define MID_SEG_COUNT		MID_RED_COUNT
-#define MID_SEG_RATE		0x01f80000
-#define MID_SEG_RATE_SHIFT	19
-#define MID_SEG_PR		0x06000000
-#define MID_SEG_PR_SHIFT	25
-#define MID_SEG_AAL5		0x08000000
-#define MID_SEG_ID		0xf0000000
-#define MID_SEG_ID_SHIFT	28
-#define MID_SEG_MAX_RATE	63
-
-#define MID_SEG_CLP		0x00000001
-#define MID_SEG_PTI		0x0000000e
-#define MID_SEG_PTI_SHIFT	1
-#define MID_SEG_VCI		0x00003ff0
-#define MID_SEG_VCI_SHIFT	4
-
-#define MID_SEG_TX_ID		0xb		/* constant identifier */
-
-/*
- * DMA entry
- */
-
-#define MID_DMA_COUNT		0xffff0000
-#define MID_DMA_COUNT_SHIFT	16
-#define MID_DMA_END		0x00000020
-#define MID_DMA_TYPE		0x0000000f
-
-#define MID_DT_JK	0x3
-#define MID_DT_WORD	0x0
-#define MID_DT_2W	0x7
-#define MID_DT_4W	0x4
-#define MID_DT_8W	0x5
-#define MID_DT_16W	0x6
-#define MID_DT_2WM	0xf
-#define MID_DT_4WM	0xc
-#define MID_DT_8WM	0xd
-#define MID_DT_16WM	0xe
-
-/* only for RX*/
-#define MID_DMA_VCI		0x0000ffc0
-#define	MID_DMA_VCI_SHIFT	6
-
-/* only for TX */
-#define MID_DMA_CHAN		0x000001c0
-#define MID_DMA_CHAN_SHIFT	6
-
-#define MID_DT_BYTE	0x1
-#define MID_DT_HWORD	0x2
-
-#endif
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
deleted file mode 100644
index 24e5134..0000000
--- a/drivers/atm/nicstar.c
+++ /dev/null
@@ -1,2759 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * nicstar.c
- *
- * Device driver supporting CBR for IDT 77201/77211 "NICStAR" based cards.
- *
- * IMPORTANT: The included file nicstarmac.c was NOT WRITTEN BY ME.
- *            It was taken from the frle-0.22 device driver.
- *            As the file doesn't have a copyright notice, in the file
- *            nicstarmac.copyright I put the copyright notice from the
- *            frle-0.22 device driver.
- *            Some code is based on the nicstar driver by M. Welsh.
- *
- * Author: Rui Prior (rprior@inescn.pt)
- * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999
- *
- *
- * (C) INESC 1999
- */
-
-/*
- * IMPORTANT INFORMATION
- *
- * There are currently three types of spinlocks:
- *
- * 1 - Per card interrupt spinlock (to protect structures and such)
- * 2 - Per SCQ scq spinlock
- * 3 - Per card resource spinlock (to access registers, etc.)
- *
- * These must NEVER be grabbed in reverse order.
- *
- */
-
-/* Header files */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/skbuff.h>
-#include <linux/atmdev.h>
-#include <linux/atm.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/hex.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/bitops.h>
-#include <linux/slab.h>
-#include <linux/idr.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-#include <linux/etherdevice.h>
-#include "nicstar.h"
-#ifdef CONFIG_ATM_NICSTAR_USE_SUNI
-#include "suni.h"
-#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
-#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-#include "idt77105.h"
-#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
-
-/* Additional code */
-
-#include "nicstarmac.c"
-
-/* Configurable parameters */
-
-#undef PHY_LOOPBACK
-#undef TX_DEBUG
-#undef RX_DEBUG
-#undef GENERAL_DEBUG
-#undef EXTRA_DEBUG
-
-/* Do not touch these */
-
-#ifdef TX_DEBUG
-#define TXPRINTK(args...) printk(args)
-#else
-#define TXPRINTK(args...)
-#endif /* TX_DEBUG */
-
-#ifdef RX_DEBUG
-#define RXPRINTK(args...) printk(args)
-#else
-#define RXPRINTK(args...)
-#endif /* RX_DEBUG */
-
-#ifdef GENERAL_DEBUG
-#define PRINTK(args...) printk(args)
-#else
-#define PRINTK(args...) do {} while (0)
-#endif /* GENERAL_DEBUG */
-
-#ifdef EXTRA_DEBUG
-#define XPRINTK(args...) printk(args)
-#else
-#define XPRINTK(args...)
-#endif /* EXTRA_DEBUG */
-
-/* Macros */
-
-#define CMD_BUSY(card) (readl((card)->membase + STAT) & NS_STAT_CMDBZ)
-
-#define NS_DELAY mdelay(1)
-
-#define PTR_DIFF(a, b)	((u32)((unsigned long)(a) - (unsigned long)(b)))
-
-#ifndef ATM_SKB
-#define ATM_SKB(s) (&(s)->atm)
-#endif
-
-#define scq_virt_to_bus(scq, p) \
-		(scq->dma + ((unsigned long)(p) - (unsigned long)(scq)->org))
-
-/* Function declarations */
-
-static u32 ns_read_sram(ns_dev * card, u32 sram_address);
-static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,
-			  int count);
-static int ns_init_card(int i, struct pci_dev *pcidev);
-static void ns_init_card_error(ns_dev * card, int error);
-static scq_info *get_scq(ns_dev *card, int size, u32 scd);
-static void free_scq(ns_dev *card, scq_info * scq, struct atm_vcc *vcc);
-static void push_rxbufs(ns_dev *, struct sk_buff *);
-static irqreturn_t ns_irq_handler(int irq, void *dev_id);
-static int ns_open(struct atm_vcc *vcc);
-static void ns_close(struct atm_vcc *vcc);
-static void fill_tst(ns_dev * card, int n, vc_map * vc);
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb);
-static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb);
-static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb, bool may_sleep);
-static void process_tsq(ns_dev * card);
-static void drain_scq(ns_dev * card, scq_info * scq, int pos);
-static void process_rsq(ns_dev * card);
-static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe);
-static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb);
-static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count);
-static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb);
-static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb);
-static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb);
-static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page);
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg);
-#ifdef EXTRA_DEBUG
-static void which_list(ns_dev * card, struct sk_buff *skb);
-#endif
-static void ns_poll(struct timer_list *unused);
-static void ns_phy_put(struct atm_dev *dev, unsigned char value,
-		       unsigned long addr);
-static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr);
-
-/* Global variables */
-
-static struct ns_dev *cards[NS_MAX_CARDS];
-static unsigned num_cards;
-static const struct atmdev_ops atm_ops = {
-	.open = ns_open,
-	.close = ns_close,
-	.ioctl = ns_ioctl,
-	.send = ns_send,
-	.send_bh = ns_send_bh,
-	.phy_put = ns_phy_put,
-	.phy_get = ns_phy_get,
-	.proc_read = ns_proc_read,
-	.owner = THIS_MODULE,
-};
-
-static struct timer_list ns_timer;
-static char *mac[NS_MAX_CARDS];
-module_param_array(mac, charp, NULL, 0);
-MODULE_DESCRIPTION("ATM NIC driver for IDT 77201/77211 \"NICStAR\" and Fore ForeRunnerLE.");
-MODULE_LICENSE("GPL");
-
-/* Functions */
-
-static int nicstar_init_one(struct pci_dev *pcidev,
-			    const struct pci_device_id *ent)
-{
-	static int index = -1;
-	unsigned int error;
-
-	index++;
-	cards[index] = NULL;
-
-	error = ns_init_card(index, pcidev);
-	if (error) {
-		cards[index--] = NULL;	/* don't increment index */
-		goto err_out;
-	}
-
-	return 0;
-err_out:
-	return -ENODEV;
-}
-
-static void nicstar_remove_one(struct pci_dev *pcidev)
-{
-	int i, j;
-	ns_dev *card = pci_get_drvdata(pcidev);
-	struct sk_buff *hb;
-	struct sk_buff *iovb;
-	struct sk_buff *lb;
-	struct sk_buff *sb;
-
-	i = card->index;
-
-	if (cards[i] == NULL)
-		return;
-
-	if (card->atmdev->phy && card->atmdev->phy->stop)
-		card->atmdev->phy->stop(card->atmdev);
-
-	/* Stop everything */
-	writel(0x00000000, card->membase + CFG);
-
-	/* De-register device */
-	atm_dev_deregister(card->atmdev);
-
-	/* Disable PCI device */
-	pci_disable_device(pcidev);
-
-	/* Free up resources */
-	j = 0;
-	PRINTK("nicstar%d: freeing %d huge buffers.\n", i, card->hbpool.count);
-	while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL) {
-		dev_kfree_skb_any(hb);
-		j++;
-	}
-	PRINTK("nicstar%d: %d huge buffers freed.\n", i, j);
-	j = 0;
-	PRINTK("nicstar%d: freeing %d iovec buffers.\n", i,
-	       card->iovpool.count);
-	while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL) {
-		dev_kfree_skb_any(iovb);
-		j++;
-	}
-	PRINTK("nicstar%d: %d iovec buffers freed.\n", i, j);
-	while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)
-		dev_kfree_skb_any(lb);
-	while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
-		dev_kfree_skb_any(sb);
-	free_scq(card, card->scq0, NULL);
-	for (j = 0; j < NS_FRSCD_NUM; j++) {
-		if (card->scd2vc[j] != NULL)
-			free_scq(card, card->scd2vc[j]->scq, card->scd2vc[j]->tx_vcc);
-	}
-	idr_destroy(&card->idr);
-	dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-			  card->rsq.org, card->rsq.dma);
-	dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-			  card->tsq.org, card->tsq.dma);
-	free_irq(card->pcidev->irq, card);
-	iounmap(card->membase);
-	kfree(card);
-}
-
-static const struct pci_device_id nicstar_pci_tbl[] = {
-	{ PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77201), 0 },
-	{0,}			/* terminate list */
-};
-
-MODULE_DEVICE_TABLE(pci, nicstar_pci_tbl);
-
-static struct pci_driver nicstar_driver = {
-	.name = "nicstar",
-	.id_table = nicstar_pci_tbl,
-	.probe = nicstar_init_one,
-	.remove = nicstar_remove_one,
-};
-
-static int __init nicstar_init(void)
-{
-	unsigned error = 0;	/* Initialized to remove compile warning */
-
-	XPRINTK("nicstar: nicstar_init() called.\n");
-
-	error = pci_register_driver(&nicstar_driver);
-
-	TXPRINTK("nicstar: TX debug enabled.\n");
-	RXPRINTK("nicstar: RX debug enabled.\n");
-	PRINTK("nicstar: General debug enabled.\n");
-#ifdef PHY_LOOPBACK
-	printk("nicstar: using PHY loopback.\n");
-#endif /* PHY_LOOPBACK */
-	XPRINTK("nicstar: nicstar_init() returned.\n");
-
-	if (!error) {
-		timer_setup(&ns_timer, ns_poll, 0);
-		ns_timer.expires = jiffies + NS_POLL_PERIOD;
-		add_timer(&ns_timer);
-	}
-
-	return error;
-}
-
-static void __exit nicstar_cleanup(void)
-{
-	XPRINTK("nicstar: nicstar_cleanup() called.\n");
-
-	timer_delete_sync(&ns_timer);
-
-	pci_unregister_driver(&nicstar_driver);
-
-	XPRINTK("nicstar: nicstar_cleanup() returned.\n");
-}
-
-static u32 ns_read_sram(ns_dev * card, u32 sram_address)
-{
-	unsigned long flags;
-	u32 data;
-	sram_address <<= 2;
-	sram_address &= 0x0007FFFC;	/* address must be dword aligned */
-	sram_address |= 0x50000000;	/* SRAM read command */
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel(sram_address, card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-	return data;
-}
-
-static void ns_write_sram(ns_dev * card, u32 sram_address, u32 * value,
-			  int count)
-{
-	unsigned long flags;
-	int i, c;
-	count--;		/* count range now is 0..3 instead of 1..4 */
-	c = count;
-	c <<= 2;		/* to use increments of 4 */
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	for (i = 0; i <= c; i += 4)
-		writel(*(value++), card->membase + i);
-	/* Note: DR# registers are the first 4 dwords in nicstar's memspace,
-	   so card->membase + DR0 == card->membase */
-	sram_address <<= 2;
-	sram_address &= 0x0007FFFC;
-	sram_address |= (0x40000000 | count);
-	writel(sram_address, card->membase + CMD);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-}
-
-static int ns_init_card(int i, struct pci_dev *pcidev)
-{
-	int j;
-	struct ns_dev *card = NULL;
-	unsigned char pci_latency;
-	unsigned error;
-	u32 data;
-	u32 u32d[4];
-	u32 ns_cfg_rctsize;
-	int bcount;
-	unsigned long membase;
-
-	error = 0;
-
-	if (pci_enable_device(pcidev)) {
-		printk("nicstar%d: can't enable PCI device\n", i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-	}
-        if (dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)) != 0) {
-                printk(KERN_WARNING
-		       "nicstar%d: No suitable DMA available.\n", i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-        }
-
-	card = kmalloc_obj(*card);
-	if (!card) {
-		printk
-		    ("nicstar%d: can't allocate memory for device structure.\n",
-		     i);
-		error = 2;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	cards[i] = card;
-	spin_lock_init(&card->int_lock);
-	spin_lock_init(&card->res_lock);
-
-	pci_set_drvdata(pcidev, card);
-
-	card->index = i;
-	card->atmdev = NULL;
-	card->pcidev = pcidev;
-	membase = pci_resource_start(pcidev, 1);
-	card->membase = ioremap(membase, NS_IOREMAP_SIZE);
-	if (!card->membase) {
-		printk("nicstar%d: can't ioremap() membase.\n", i);
-		error = 3;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	PRINTK("nicstar%d: membase at 0x%p.\n", i, card->membase);
-
-	pci_set_master(pcidev);
-
-	if (pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency) != 0) {
-		printk("nicstar%d: can't read PCI latency timer.\n", i);
-		error = 6;
-		ns_init_card_error(card, error);
-		return error;
-	}
-#ifdef NS_PCI_LATENCY
-	if (pci_latency < NS_PCI_LATENCY) {
-		PRINTK("nicstar%d: setting PCI latency timer to %d.\n", i,
-		       NS_PCI_LATENCY);
-		for (j = 1; j < 4; j++) {
-			if (pci_write_config_byte
-			    (pcidev, PCI_LATENCY_TIMER, NS_PCI_LATENCY) != 0)
-				break;
-		}
-		if (j == 4) {
-			printk
-			    ("nicstar%d: can't set PCI latency timer to %d.\n",
-			     i, NS_PCI_LATENCY);
-			error = 7;
-			ns_init_card_error(card, error);
-			return error;
-		}
-	}
-#endif /* NS_PCI_LATENCY */
-
-	/* Clear timer overflow */
-	data = readl(card->membase + STAT);
-	if (data & NS_STAT_TMROF)
-		writel(NS_STAT_TMROF, card->membase + STAT);
-
-	/* Software reset */
-	writel(NS_CFG_SWRST, card->membase + CFG);
-	NS_DELAY;
-	writel(0x00000000, card->membase + CFG);
-
-	/* PHY reset */
-	writel(0x00000008, card->membase + GP);
-	NS_DELAY;
-	writel(0x00000001, card->membase + GP);
-	NS_DELAY;
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_WRITE_UTILITY | 0x00000100, card->membase + CMD);	/* Sync UTOPIA with SAR clock */
-	NS_DELAY;
-
-	/* Detect PHY type */
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_READ_UTILITY | 0x00000200, card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0);
-	switch (data) {
-	case 0x00000009:
-		printk("nicstar%d: PHY seems to be 25 Mbps.\n", i);
-		card->max_pcr = ATM_25_PCR;
-		while (CMD_BUSY(card)) ;
-		writel(0x00000008, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000200, card->membase + CMD);
-		/* Clear an eventual pending interrupt */
-		writel(NS_STAT_SFBQF, card->membase + STAT);
-#ifdef PHY_LOOPBACK
-		while (CMD_BUSY(card)) ;
-		writel(0x00000022, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000202, card->membase + CMD);
-#endif /* PHY_LOOPBACK */
-		break;
-	case 0x00000030:
-	case 0x00000031:
-		printk("nicstar%d: PHY seems to be 155 Mbps.\n", i);
-		card->max_pcr = ATM_OC3_PCR;
-#ifdef PHY_LOOPBACK
-		while (CMD_BUSY(card)) ;
-		writel(0x00000002, card->membase + DR0);
-		writel(NS_CMD_WRITE_UTILITY | 0x00000205, card->membase + CMD);
-#endif /* PHY_LOOPBACK */
-		break;
-	default:
-		printk("nicstar%d: unknown PHY type (0x%08X).\n", i, data);
-		error = 8;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	writel(0x00000000, card->membase + GP);
-
-	/* Determine SRAM size */
-	data = 0x76543210;
-	ns_write_sram(card, 0x1C003, &data, 1);
-	data = 0x89ABCDEF;
-	ns_write_sram(card, 0x14003, &data, 1);
-	if (ns_read_sram(card, 0x14003) == 0x89ABCDEF &&
-	    ns_read_sram(card, 0x1C003) == 0x76543210)
-		card->sram_size = 128;
-	else
-		card->sram_size = 32;
-	PRINTK("nicstar%d: %dK x 32bit SRAM size.\n", i, card->sram_size);
-
-	card->rct_size = NS_MAX_RCTSIZE;
-
-#if (NS_MAX_RCTSIZE == 4096)
-	if (card->sram_size == 128)
-		printk
-		    ("nicstar%d: limiting maximum VCI. See NS_MAX_RCTSIZE in nicstar.h\n",
-		     i);
-#elif (NS_MAX_RCTSIZE == 16384)
-	if (card->sram_size == 32) {
-		printk
-		    ("nicstar%d: wasting memory. See NS_MAX_RCTSIZE in nicstar.h\n",
-		     i);
-		card->rct_size = 4096;
-	}
-#else
-#error NS_MAX_RCTSIZE must be either 4096 or 16384 in nicstar.c
-#endif
-
-	card->vpibits = NS_VPIBITS;
-	if (card->rct_size == 4096)
-		card->vcibits = 12 - NS_VPIBITS;
-	else			/* card->rct_size == 16384 */
-		card->vcibits = 14 - NS_VPIBITS;
-
-	/* Initialize the nicstar eeprom/eprom stuff, for the MAC addr */
-	if (mac[i] == NULL)
-		nicstar_init_eprom(card->membase);
-
-	/* Set the VPI/VCI MSb mask to zero so we can receive OAM cells */
-	writel(0x00000000, card->membase + VPM);
-
-	card->intcnt = 0;
-	if (request_irq
-	    (pcidev->irq, &ns_irq_handler, IRQF_SHARED, "nicstar", card) != 0) {
-		pr_err("nicstar%d: can't allocate IRQ %d.\n", i, pcidev->irq);
-		error = 9;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Initialize TSQ */
-	card->tsq.org = dma_alloc_coherent(&card->pcidev->dev,
-					   NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-					   &card->tsq.dma, GFP_KERNEL);
-	if (card->tsq.org == NULL) {
-		printk("nicstar%d: can't allocate TSQ.\n", i);
-		error = 10;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	card->tsq.base = PTR_ALIGN(card->tsq.org, NS_TSQ_ALIGNMENT);
-	card->tsq.next = card->tsq.base;
-	card->tsq.last = card->tsq.base + (NS_TSQ_NUM_ENTRIES - 1);
-	for (j = 0; j < NS_TSQ_NUM_ENTRIES; j++)
-		ns_tsi_init(card->tsq.base + j);
-	writel(0x00000000, card->membase + TSQH);
-	writel(ALIGN(card->tsq.dma, NS_TSQ_ALIGNMENT), card->membase + TSQB);
-	PRINTK("nicstar%d: TSQ base at 0x%p.\n", i, card->tsq.base);
-
-	/* Initialize RSQ */
-	card->rsq.org = dma_alloc_coherent(&card->pcidev->dev,
-					   NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-					   &card->rsq.dma, GFP_KERNEL);
-	if (card->rsq.org == NULL) {
-		printk("nicstar%d: can't allocate RSQ.\n", i);
-		error = 11;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	card->rsq.base = PTR_ALIGN(card->rsq.org, NS_RSQ_ALIGNMENT);
-	card->rsq.next = card->rsq.base;
-	card->rsq.last = card->rsq.base + (NS_RSQ_NUM_ENTRIES - 1);
-	for (j = 0; j < NS_RSQ_NUM_ENTRIES; j++)
-		ns_rsqe_init(card->rsq.base + j);
-	writel(0x00000000, card->membase + RSQH);
-	writel(ALIGN(card->rsq.dma, NS_RSQ_ALIGNMENT), card->membase + RSQB);
-	PRINTK("nicstar%d: RSQ base at 0x%p.\n", i, card->rsq.base);
-
-	/* Initialize SCQ0, the only VBR SCQ used */
-	card->scq1 = NULL;
-	card->scq2 = NULL;
-	card->scq0 = get_scq(card, VBR_SCQSIZE, NS_VRSCD0);
-	if (card->scq0 == NULL) {
-		printk("nicstar%d: can't get SCQ0.\n", i);
-		error = 12;
-		ns_init_card_error(card, error);
-		return error;
-	}
-	u32d[0] = scq_virt_to_bus(card->scq0, card->scq0->base);
-	u32d[1] = (u32) 0x00000000;
-	u32d[2] = (u32) 0xffffffff;
-	u32d[3] = (u32) 0x00000000;
-	ns_write_sram(card, NS_VRSCD0, u32d, 4);
-	ns_write_sram(card, NS_VRSCD1, u32d, 4);	/* These last two won't be used */
-	ns_write_sram(card, NS_VRSCD2, u32d, 4);	/* but are initialized, just in case... */
-	card->scq0->scd = NS_VRSCD0;
-	PRINTK("nicstar%d: VBR-SCQ0 base at 0x%p.\n", i, card->scq0->base);
-
-	/* Initialize TSTs */
-	card->tst_addr = NS_TST0;
-	card->tst_free_entries = NS_TST_NUM_ENTRIES;
-	data = NS_TST_OPCODE_VARIABLE;
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		ns_write_sram(card, NS_TST0 + j, &data, 1);
-	data = ns_tste_make(NS_TST_OPCODE_END, NS_TST0);
-	ns_write_sram(card, NS_TST0 + NS_TST_NUM_ENTRIES, &data, 1);
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		ns_write_sram(card, NS_TST1 + j, &data, 1);
-	data = ns_tste_make(NS_TST_OPCODE_END, NS_TST1);
-	ns_write_sram(card, NS_TST1 + NS_TST_NUM_ENTRIES, &data, 1);
-	for (j = 0; j < NS_TST_NUM_ENTRIES; j++)
-		card->tste2vc[j] = NULL;
-	writel(NS_TST0 << 2, card->membase + TSTB);
-
-	/* Initialize RCT. AAL type is set on opening the VC. */
-#ifdef RCQ_SUPPORT
-	u32d[0] = NS_RCTE_RAWCELLINTEN;
-#else
-	u32d[0] = 0x00000000;
-#endif /* RCQ_SUPPORT */
-	u32d[1] = 0x00000000;
-	u32d[2] = 0x00000000;
-	u32d[3] = 0xFFFFFFFF;
-	for (j = 0; j < card->rct_size; j++)
-		ns_write_sram(card, j * 4, u32d, 4);
-
-	memset(card->vcmap, 0, sizeof(card->vcmap));
-
-	for (j = 0; j < NS_FRSCD_NUM; j++)
-		card->scd2vc[j] = NULL;
-
-	/* Initialize buffer levels */
-	card->sbnr.min = MIN_SB;
-	card->sbnr.init = NUM_SB;
-	card->sbnr.max = MAX_SB;
-	card->lbnr.min = MIN_LB;
-	card->lbnr.init = NUM_LB;
-	card->lbnr.max = MAX_LB;
-	card->iovnr.min = MIN_IOVB;
-	card->iovnr.init = NUM_IOVB;
-	card->iovnr.max = MAX_IOVB;
-	card->hbnr.min = MIN_HB;
-	card->hbnr.init = NUM_HB;
-	card->hbnr.max = MAX_HB;
-
-	card->sm_handle = NULL;
-	card->sm_addr = 0x00000000;
-	card->lg_handle = NULL;
-	card->lg_addr = 0x00000000;
-
-	card->efbie = 1;	/* To prevent push_rxbufs from enabling the interrupt */
-
-	idr_init(&card->idr);
-
-	/* Pre-allocate some huge buffers */
-	skb_queue_head_init(&card->hbpool.queue);
-	card->hbpool.count = 0;
-	for (j = 0; j < NUM_HB; j++) {
-		struct sk_buff *hb;
-		hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
-		if (hb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d huge buffers.\n",
-			     i, j, NUM_HB);
-			error = 13;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(hb) = BUF_NONE;
-		skb_queue_tail(&card->hbpool.queue, hb);
-		card->hbpool.count++;
-	}
-
-	/* Allocate large buffers */
-	skb_queue_head_init(&card->lbpool.queue);
-	card->lbpool.count = 0;	/* Not used */
-	for (j = 0; j < NUM_LB; j++) {
-		struct sk_buff *lb;
-		lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
-		if (lb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d large buffers.\n",
-			     i, j, NUM_LB);
-			error = 14;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(lb) = BUF_LG;
-		skb_queue_tail(&card->lbpool.queue, lb);
-		skb_reserve(lb, NS_SMBUFSIZE);
-		push_rxbufs(card, lb);
-		/* Due to the implementation of push_rxbufs() this is 1, not 0 */
-		if (j == 1) {
-			card->rcbuf = lb;
-			card->rawcell = (struct ns_rcqe *) lb->data;
-			card->rawch = NS_PRV_DMA(lb);
-		}
-	}
-	/* Test for strange behaviour which leads to crashes */
-	if ((bcount =
-	     ns_stat_lfbqc_get(readl(card->membase + STAT))) < card->lbnr.min) {
-		printk
-		    ("nicstar%d: Strange... Just allocated %d large buffers and lfbqc = %d.\n",
-		     i, j, bcount);
-		error = 14;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Allocate small buffers */
-	skb_queue_head_init(&card->sbpool.queue);
-	card->sbpool.count = 0;	/* Not used */
-	for (j = 0; j < NUM_SB; j++) {
-		struct sk_buff *sb;
-		sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
-		if (sb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d small buffers.\n",
-			     i, j, NUM_SB);
-			error = 15;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(sb) = BUF_SM;
-		skb_queue_tail(&card->sbpool.queue, sb);
-		skb_reserve(sb, NS_AAL0_HEADER);
-		push_rxbufs(card, sb);
-	}
-	/* Test for strange behaviour which leads to crashes */
-	if ((bcount =
-	     ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min) {
-		printk
-		    ("nicstar%d: Strange... Just allocated %d small buffers and sfbqc = %d.\n",
-		     i, j, bcount);
-		error = 15;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	/* Allocate iovec buffers */
-	skb_queue_head_init(&card->iovpool.queue);
-	card->iovpool.count = 0;
-	for (j = 0; j < NUM_IOVB; j++) {
-		struct sk_buff *iovb;
-		iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
-		if (iovb == NULL) {
-			printk
-			    ("nicstar%d: can't allocate %dth of %d iovec buffers.\n",
-			     i, j, NUM_IOVB);
-			error = 16;
-			ns_init_card_error(card, error);
-			return error;
-		}
-		NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-		skb_queue_tail(&card->iovpool.queue, iovb);
-		card->iovpool.count++;
-	}
-
-	/* Configure NICStAR */
-	if (card->rct_size == 4096)
-		ns_cfg_rctsize = NS_CFG_RCTSIZE_4096_ENTRIES;
-	else			/* (card->rct_size == 16384) */
-		ns_cfg_rctsize = NS_CFG_RCTSIZE_16384_ENTRIES;
-
-	card->efbie = 1;
-
-	/* Register device */
-	card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops,
-					-1, NULL);
-	if (card->atmdev == NULL) {
-		printk("nicstar%d: can't register device.\n", i);
-		error = 17;
-		ns_init_card_error(card, error);
-		return error;
-	}
-
-	if (mac[i] == NULL || !mac_pton(mac[i], card->atmdev->esi)) {
-		nicstar_read_eprom(card->membase, NICSTAR_EPROM_MAC_ADDR_OFFSET,
-				   card->atmdev->esi, 6);
-		if (ether_addr_equal(card->atmdev->esi, "\x00\x00\x00\x00\x00\x00")) {
-			nicstar_read_eprom(card->membase,
-					   NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT,
-					   card->atmdev->esi, 6);
-		}
-	}
-
-	printk("nicstar%d: MAC address %pM\n", i, card->atmdev->esi);
-
-	card->atmdev->dev_data = card;
-	card->atmdev->ci_range.vpi_bits = card->vpibits;
-	card->atmdev->ci_range.vci_bits = card->vcibits;
-	card->atmdev->link_rate = card->max_pcr;
-	card->atmdev->phy = NULL;
-
-#ifdef CONFIG_ATM_NICSTAR_USE_SUNI
-	if (card->max_pcr == ATM_OC3_PCR)
-		suni_init(card->atmdev);
-#endif /* CONFIG_ATM_NICSTAR_USE_SUNI */
-
-#ifdef CONFIG_ATM_NICSTAR_USE_IDT77105
-	if (card->max_pcr == ATM_25_PCR)
-		idt77105_init(card->atmdev);
-#endif /* CONFIG_ATM_NICSTAR_USE_IDT77105 */
-
-	if (card->atmdev->phy && card->atmdev->phy->start)
-		card->atmdev->phy->start(card->atmdev);
-
-	writel(NS_CFG_RXPATH | NS_CFG_SMBUFSIZE | NS_CFG_LGBUFSIZE | NS_CFG_EFBIE | NS_CFG_RSQSIZE | NS_CFG_VPIBITS | ns_cfg_rctsize | NS_CFG_RXINT_NODELAY | NS_CFG_RAWIE |	/* Only enabled if RCQ_SUPPORT */
-	       NS_CFG_RSQAFIE | NS_CFG_TXEN | NS_CFG_TXIE | NS_CFG_TSQFIE_OPT |	/* Only enabled if ENABLE_TSQFIE */
-	       NS_CFG_PHYIE, card->membase + CFG);
-
-	num_cards++;
-
-	return error;
-}
-
-static void ns_init_card_error(ns_dev *card, int error)
-{
-	if (error >= 17) {
-		writel(0x00000000, card->membase + CFG);
-	}
-	if (error >= 16) {
-		struct sk_buff *iovb;
-		while ((iovb = skb_dequeue(&card->iovpool.queue)) != NULL)
-			dev_kfree_skb_any(iovb);
-	}
-	if (error >= 15) {
-		struct sk_buff *sb;
-		while ((sb = skb_dequeue(&card->sbpool.queue)) != NULL)
-			dev_kfree_skb_any(sb);
-		free_scq(card, card->scq0, NULL);
-	}
-	if (error >= 14) {
-		struct sk_buff *lb;
-		while ((lb = skb_dequeue(&card->lbpool.queue)) != NULL)
-			dev_kfree_skb_any(lb);
-	}
-	if (error >= 13) {
-		struct sk_buff *hb;
-		while ((hb = skb_dequeue(&card->hbpool.queue)) != NULL)
-			dev_kfree_skb_any(hb);
-	}
-	if (error >= 12) {
-		dma_free_coherent(&card->pcidev->dev, NS_RSQSIZE + NS_RSQ_ALIGNMENT,
-				card->rsq.org, card->rsq.dma);
-	}
-	if (error >= 11) {
-		dma_free_coherent(&card->pcidev->dev, NS_TSQSIZE + NS_TSQ_ALIGNMENT,
-				card->tsq.org, card->tsq.dma);
-	}
-	if (error >= 10) {
-		free_irq(card->pcidev->irq, card);
-	}
-	if (error >= 4) {
-		iounmap(card->membase);
-	}
-	if (error >= 3) {
-		pci_disable_device(card->pcidev);
-		kfree(card);
-	}
-}
-
-static scq_info *get_scq(ns_dev *card, int size, u32 scd)
-{
-	scq_info *scq;
-
-	if (size != VBR_SCQSIZE && size != CBR_SCQSIZE)
-		return NULL;
-
-	scq = kmalloc_obj(*scq);
-	if (!scq)
-		return NULL;
-        scq->org = dma_alloc_coherent(&card->pcidev->dev,
-				      2 * size,  &scq->dma, GFP_KERNEL);
-	if (!scq->org) {
-		kfree(scq);
-		return NULL;
-	}
-	scq->skb = kzalloc_objs(*scq->skb, size / NS_SCQE_SIZE);
-	if (!scq->skb) {
-		dma_free_coherent(&card->pcidev->dev,
-				  2 * size, scq->org, scq->dma);
-		kfree(scq);
-		return NULL;
-	}
-	scq->num_entries = size / NS_SCQE_SIZE;
-	scq->base = PTR_ALIGN(scq->org, size);
-	scq->next = scq->base;
-	scq->last = scq->base + (scq->num_entries - 1);
-	scq->tail = scq->last;
-	scq->scd = scd;
-	scq->tbd_count = 0;
-	init_waitqueue_head(&scq->scqfull_waitq);
-	scq->full = 0;
-	spin_lock_init(&scq->lock);
-
-	return scq;
-}
-
-/* For variable rate SCQ vcc must be NULL */
-static void free_scq(ns_dev *card, scq_info *scq, struct atm_vcc *vcc)
-{
-	int i;
-
-	if (scq->num_entries == VBR_SCQ_NUM_ENTRIES)
-		for (i = 0; i < scq->num_entries; i++) {
-			if (scq->skb[i] != NULL) {
-				vcc = ATM_SKB(scq->skb[i])->vcc;
-				if (vcc->pop != NULL)
-					vcc->pop(vcc, scq->skb[i]);
-				else
-					dev_kfree_skb_any(scq->skb[i]);
-			}
-	} else {		/* vcc must be != NULL */
-
-		if (vcc == NULL) {
-			printk
-			    ("nicstar: free_scq() called with vcc == NULL for fixed rate scq.");
-			for (i = 0; i < scq->num_entries; i++)
-				dev_kfree_skb_any(scq->skb[i]);
-		} else
-			for (i = 0; i < scq->num_entries; i++) {
-				if (scq->skb[i] != NULL) {
-					if (vcc->pop != NULL)
-						vcc->pop(vcc, scq->skb[i]);
-					else
-						dev_kfree_skb_any(scq->skb[i]);
-				}
-			}
-	}
-	kfree(scq->skb);
-	dma_free_coherent(&card->pcidev->dev,
-			  2 * (scq->num_entries == VBR_SCQ_NUM_ENTRIES ?
-			       VBR_SCQSIZE : CBR_SCQSIZE),
-			  scq->org, scq->dma);
-	kfree(scq);
-}
-
-/* The handles passed must be pointers to the sk_buff containing the small
-   or large buffer(s) cast to u32. */
-static void push_rxbufs(ns_dev * card, struct sk_buff *skb)
-{
-	struct sk_buff *handle1, *handle2;
-	int id1, id2;
-	u32 addr1, addr2;
-	u32 stat;
-	unsigned long flags;
-
-	/* *BARF* */
-	handle2 = NULL;
-	addr2 = 0;
-	handle1 = skb;
-	addr1 = dma_map_single(&card->pcidev->dev,
-			       skb->data,
-			       (NS_PRV_BUFTYPE(skb) == BUF_SM
-				? NS_SMSKBSIZE : NS_LGSKBSIZE),
-			       DMA_TO_DEVICE);
-	NS_PRV_DMA(skb) = addr1; /* save so we can unmap later */
-
-#ifdef GENERAL_DEBUG
-	if (!addr1)
-		printk("nicstar%d: push_rxbufs called with addr1 = 0.\n",
-		       card->index);
-#endif /* GENERAL_DEBUG */
-
-	stat = readl(card->membase + STAT);
-	card->sbfqc = ns_stat_sfbqc_get(stat);
-	card->lbfqc = ns_stat_lfbqc_get(stat);
-	if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
-		if (!addr2) {
-			if (card->sm_addr) {
-				addr2 = card->sm_addr;
-				handle2 = card->sm_handle;
-				card->sm_addr = 0x00000000;
-				card->sm_handle = NULL;
-			} else {	/* (!sm_addr) */
-
-				card->sm_addr = addr1;
-				card->sm_handle = handle1;
-			}
-		}
-	} else {		/* buf_type == BUF_LG */
-
-		if (!addr2) {
-			if (card->lg_addr) {
-				addr2 = card->lg_addr;
-				handle2 = card->lg_handle;
-				card->lg_addr = 0x00000000;
-				card->lg_handle = NULL;
-			} else {	/* (!lg_addr) */
-
-				card->lg_addr = addr1;
-				card->lg_handle = handle1;
-			}
-		}
-	}
-
-	if (addr2) {
-		if (NS_PRV_BUFTYPE(skb) == BUF_SM) {
-			if (card->sbfqc >= card->sbnr.max) {
-				skb_unlink(handle1, &card->sbpool.queue);
-				dev_kfree_skb_any(handle1);
-				skb_unlink(handle2, &card->sbpool.queue);
-				dev_kfree_skb_any(handle2);
-				return;
-			} else
-				card->sbfqc += 2;
-		} else {	/* (buf_type == BUF_LG) */
-
-			if (card->lbfqc >= card->lbnr.max) {
-				skb_unlink(handle1, &card->lbpool.queue);
-				dev_kfree_skb_any(handle1);
-				skb_unlink(handle2, &card->lbpool.queue);
-				dev_kfree_skb_any(handle2);
-				return;
-			} else
-				card->lbfqc += 2;
-		}
-
-		id1 = idr_alloc(&card->idr, handle1, 0, 0, GFP_ATOMIC);
-		if (id1 < 0)
-			goto out;
-
-		id2 = idr_alloc(&card->idr, handle2, 0, 0, GFP_ATOMIC);
-		if (id2 < 0)
-			goto out;
-
-		spin_lock_irqsave(&card->res_lock, flags);
-		while (CMD_BUSY(card)) ;
-		writel(addr2, card->membase + DR3);
-		writel(id2, card->membase + DR2);
-		writel(addr1, card->membase + DR1);
-		writel(id1, card->membase + DR0);
-		writel(NS_CMD_WRITE_FREEBUFQ | NS_PRV_BUFTYPE(skb),
-		       card->membase + CMD);
-		spin_unlock_irqrestore(&card->res_lock, flags);
-
-		XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n",
-			card->index,
-			(NS_PRV_BUFTYPE(skb) == BUF_SM ? "small" : "large"),
-			addr1, addr2);
-	}
-
-	if (!card->efbie && card->sbfqc >= card->sbnr.min &&
-	    card->lbfqc >= card->lbnr.min) {
-		card->efbie = 1;
-		writel((readl(card->membase + CFG) | NS_CFG_EFBIE),
-		       card->membase + CFG);
-	}
-
-out:
-	return;
-}
-
-static irqreturn_t ns_irq_handler(int irq, void *dev_id)
-{
-	u32 stat_r;
-	ns_dev *card;
-	struct atm_dev *dev;
-	unsigned long flags;
-
-	card = (ns_dev *) dev_id;
-	dev = card->atmdev;
-	card->intcnt++;
-
-	PRINTK("nicstar%d: NICStAR generated an interrupt\n", card->index);
-
-	spin_lock_irqsave(&card->int_lock, flags);
-
-	stat_r = readl(card->membase + STAT);
-
-	/* Transmit Status Indicator has been written to T. S. Queue */
-	if (stat_r & NS_STAT_TSIF) {
-		TXPRINTK("nicstar%d: TSI interrupt\n", card->index);
-		process_tsq(card);
-		writel(NS_STAT_TSIF, card->membase + STAT);
-	}
-
-	/* Incomplete CS-PDU has been transmitted */
-	if (stat_r & NS_STAT_TXICP) {
-		writel(NS_STAT_TXICP, card->membase + STAT);
-		TXPRINTK("nicstar%d: Incomplete CS-PDU transmitted.\n",
-			 card->index);
-	}
-
-	/* Transmit Status Queue 7/8 full */
-	if (stat_r & NS_STAT_TSQF) {
-		writel(NS_STAT_TSQF, card->membase + STAT);
-		PRINTK("nicstar%d: TSQ full.\n", card->index);
-		process_tsq(card);
-	}
-
-	/* Timer overflow */
-	if (stat_r & NS_STAT_TMROF) {
-		writel(NS_STAT_TMROF, card->membase + STAT);
-		PRINTK("nicstar%d: Timer overflow.\n", card->index);
-	}
-
-	/* PHY device interrupt signal active */
-	if (stat_r & NS_STAT_PHYI) {
-		writel(NS_STAT_PHYI, card->membase + STAT);
-		PRINTK("nicstar%d: PHY interrupt.\n", card->index);
-		if (dev->phy && dev->phy->interrupt) {
-			dev->phy->interrupt(dev);
-		}
-	}
-
-	/* Small Buffer Queue is full */
-	if (stat_r & NS_STAT_SFBQF) {
-		writel(NS_STAT_SFBQF, card->membase + STAT);
-		printk("nicstar%d: Small free buffer queue is full.\n",
-		       card->index);
-	}
-
-	/* Large Buffer Queue is full */
-	if (stat_r & NS_STAT_LFBQF) {
-		writel(NS_STAT_LFBQF, card->membase + STAT);
-		printk("nicstar%d: Large free buffer queue is full.\n",
-		       card->index);
-	}
-
-	/* Receive Status Queue is full */
-	if (stat_r & NS_STAT_RSQF) {
-		writel(NS_STAT_RSQF, card->membase + STAT);
-		printk("nicstar%d: RSQ full.\n", card->index);
-		process_rsq(card);
-	}
-
-	/* Complete CS-PDU received */
-	if (stat_r & NS_STAT_EOPDU) {
-		RXPRINTK("nicstar%d: End of CS-PDU received.\n", card->index);
-		process_rsq(card);
-		writel(NS_STAT_EOPDU, card->membase + STAT);
-	}
-
-	/* Raw cell received */
-	if (stat_r & NS_STAT_RAWCF) {
-		writel(NS_STAT_RAWCF, card->membase + STAT);
-#ifndef RCQ_SUPPORT
-		printk("nicstar%d: Raw cell received and no support yet...\n",
-		       card->index);
-#endif /* RCQ_SUPPORT */
-		/* NOTE: the following procedure may keep a raw cell pending until the
-		   next interrupt. As this preliminary support is only meant to
-		   avoid buffer leakage, this is not an issue. */
-		while (readl(card->membase + RAWCT) != card->rawch) {
-
-			if (ns_rcqe_islast(card->rawcell)) {
-				struct sk_buff *oldbuf;
-
-				oldbuf = card->rcbuf;
-				card->rcbuf = idr_find(&card->idr,
-						       ns_rcqe_nextbufhandle(card->rawcell));
-				card->rawch = NS_PRV_DMA(card->rcbuf);
-				card->rawcell = (struct ns_rcqe *)
-						card->rcbuf->data;
-				recycle_rx_buf(card, oldbuf);
-			} else {
-				card->rawch += NS_RCQE_SIZE;
-				card->rawcell++;
-			}
-		}
-	}
-
-	/* Small buffer queue is empty */
-	if (stat_r & NS_STAT_SFBQE) {
-		int i;
-		struct sk_buff *sb;
-
-		writel(NS_STAT_SFBQE, card->membase + STAT);
-		printk("nicstar%d: Small free buffer queue empty.\n",
-		       card->index);
-		for (i = 0; i < card->sbnr.min; i++) {
-			sb = dev_alloc_skb(NS_SMSKBSIZE);
-			if (sb == NULL) {
-				writel(readl(card->membase + CFG) &
-				       ~NS_CFG_EFBIE, card->membase + CFG);
-				card->efbie = 0;
-				break;
-			}
-			NS_PRV_BUFTYPE(sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, sb);
-			skb_reserve(sb, NS_AAL0_HEADER);
-			push_rxbufs(card, sb);
-		}
-		card->sbfqc = i;
-		process_rsq(card);
-	}
-
-	/* Large buffer queue empty */
-	if (stat_r & NS_STAT_LFBQE) {
-		int i;
-		struct sk_buff *lb;
-
-		writel(NS_STAT_LFBQE, card->membase + STAT);
-		printk("nicstar%d: Large free buffer queue empty.\n",
-		       card->index);
-		for (i = 0; i < card->lbnr.min; i++) {
-			lb = dev_alloc_skb(NS_LGSKBSIZE);
-			if (lb == NULL) {
-				writel(readl(card->membase + CFG) &
-				       ~NS_CFG_EFBIE, card->membase + CFG);
-				card->efbie = 0;
-				break;
-			}
-			NS_PRV_BUFTYPE(lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, lb);
-			skb_reserve(lb, NS_SMBUFSIZE);
-			push_rxbufs(card, lb);
-		}
-		card->lbfqc = i;
-		process_rsq(card);
-	}
-
-	/* Receive Status Queue is 7/8 full */
-	if (stat_r & NS_STAT_RSQAF) {
-		writel(NS_STAT_RSQAF, card->membase + STAT);
-		RXPRINTK("nicstar%d: RSQ almost full.\n", card->index);
-		process_rsq(card);
-	}
-
-	spin_unlock_irqrestore(&card->int_lock, flags);
-	PRINTK("nicstar%d: end of interrupt service\n", card->index);
-	return IRQ_HANDLED;
-}
-
-static int ns_open(struct atm_vcc *vcc)
-{
-	ns_dev *card;
-	vc_map *vc;
-	unsigned long tmpl, modl;
-	int tcr, tcra;		/* target cell rate, and absolute value */
-	int n = 0;		/* Number of entries in the TST. Initialized to remove
-				   the compiler warning. */
-	u32 u32d[4];
-	int frscdi = 0;		/* Index of the SCD. Initialized to remove the compiler
-				   warning. How I wish compilers were clever enough to
-				   tell which variables can truly be used
-				   uninitialized... */
-	int inuse;		/* tx or rx vc already in use by another vcc */
-	short vpi = vcc->vpi;
-	int vci = vcc->vci;
-
-	card = (ns_dev *) vcc->dev->dev_data;
-	PRINTK("nicstar%d: opening vpi.vci %d.%d \n", card->index, (int)vpi,
-	       vci);
-	if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
-		PRINTK("nicstar%d: unsupported AAL.\n", card->index);
-		return -EINVAL;
-	}
-
-	vc = &(card->vcmap[vpi << card->vcibits | vci]);
-	vcc->dev_data = vc;
-
-	inuse = 0;
-	if (vcc->qos.txtp.traffic_class != ATM_NONE && vc->tx)
-		inuse = 1;
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE && vc->rx)
-		inuse += 2;
-	if (inuse) {
-		printk("nicstar%d: %s vci already in use.\n", card->index,
-		       inuse == 1 ? "tx" : inuse == 2 ? "rx" : "tx and rx");
-		return -EINVAL;
-	}
-
-	set_bit(ATM_VF_ADDR, &vcc->flags);
-
-	/* NOTE: You are not allowed to modify an open connection's QOS. To change
-	   that, remove the ATM_VF_PARTIAL flag checking. There may be other changes
-	   needed to do that. */
-	if (!test_bit(ATM_VF_PARTIAL, &vcc->flags)) {
-		scq_info *scq;
-
-		set_bit(ATM_VF_PARTIAL, &vcc->flags);
-		if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-			/* Check requested cell rate and availability of SCD */
-			if (vcc->qos.txtp.max_pcr == 0 && vcc->qos.txtp.pcr == 0
-			    && vcc->qos.txtp.min_pcr == 0) {
-				PRINTK
-				    ("nicstar%d: trying to open a CBR vc with cell rate = 0 \n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			}
-
-			tcr = atm_pcr_goal(&(vcc->qos.txtp));
-			tcra = tcr >= 0 ? tcr : -tcr;
-
-			PRINTK("nicstar%d: target cell rate = %d.\n",
-			       card->index, vcc->qos.txtp.max_pcr);
-
-			tmpl =
-			    (unsigned long)tcra *(unsigned long)
-			    NS_TST_NUM_ENTRIES;
-			modl = tmpl % card->max_pcr;
-
-			n = (int)(tmpl / card->max_pcr);
-			if (tcr > 0) {
-				if (modl > 0)
-					n++;
-			} else if (tcr == 0) {
-				if ((n =
-				     (card->tst_free_entries -
-				      NS_TST_RESERVED)) <= 0) {
-					PRINTK
-					    ("nicstar%d: no CBR bandwidth free.\n",
-					     card->index);
-					clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-					clear_bit(ATM_VF_ADDR, &vcc->flags);
-					return -EINVAL;
-				}
-			}
-
-			if (n == 0) {
-				printk
-				    ("nicstar%d: selected bandwidth < granularity.\n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			}
-
-			if (n > (card->tst_free_entries - NS_TST_RESERVED)) {
-				PRINTK
-				    ("nicstar%d: not enough free CBR bandwidth.\n",
-				     card->index);
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EINVAL;
-			} else
-				card->tst_free_entries -= n;
-
-			XPRINTK("nicstar%d: writing %d tst entries.\n",
-				card->index, n);
-			for (frscdi = 0; frscdi < NS_FRSCD_NUM; frscdi++) {
-				if (card->scd2vc[frscdi] == NULL) {
-					card->scd2vc[frscdi] = vc;
-					break;
-				}
-			}
-			if (frscdi == NS_FRSCD_NUM) {
-				PRINTK
-				    ("nicstar%d: no SCD available for CBR channel.\n",
-				     card->index);
-				card->tst_free_entries += n;
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -EBUSY;
-			}
-
-			vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE;
-
-			scq = get_scq(card, CBR_SCQSIZE, vc->cbr_scd);
-			if (scq == NULL) {
-				PRINTK("nicstar%d: can't get fixed rate SCQ.\n",
-				       card->index);
-				card->scd2vc[frscdi] = NULL;
-				card->tst_free_entries += n;
-				clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-				clear_bit(ATM_VF_ADDR, &vcc->flags);
-				return -ENOMEM;
-			}
-			vc->scq = scq;
-			u32d[0] = scq_virt_to_bus(scq, scq->base);
-			u32d[1] = (u32) 0x00000000;
-			u32d[2] = (u32) 0xffffffff;
-			u32d[3] = (u32) 0x00000000;
-			ns_write_sram(card, vc->cbr_scd, u32d, 4);
-
-			fill_tst(card, n, vc);
-		} else if (vcc->qos.txtp.traffic_class == ATM_UBR) {
-			vc->cbr_scd = 0x00000000;
-			vc->scq = card->scq0;
-		}
-
-		if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-			vc->tx = 1;
-			vc->tx_vcc = vcc;
-			vc->tbd_count = 0;
-		}
-		if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-			u32 status;
-
-			vc->rx = 1;
-			vc->rx_vcc = vcc;
-			vc->rx_iov = NULL;
-
-			/* Open the connection in hardware */
-			if (vcc->qos.aal == ATM_AAL5)
-				status = NS_RCTE_AAL5 | NS_RCTE_CONNECTOPEN;
-			else	/* vcc->qos.aal == ATM_AAL0 */
-				status = NS_RCTE_AAL0 | NS_RCTE_CONNECTOPEN;
-#ifdef RCQ_SUPPORT
-			status |= NS_RCTE_RAWCELLINTEN;
-#endif /* RCQ_SUPPORT */
-			ns_write_sram(card,
-				      NS_RCT +
-				      (vpi << card->vcibits | vci) *
-				      NS_RCT_ENTRY_SIZE, &status, 1);
-		}
-
-	}
-
-	set_bit(ATM_VF_READY, &vcc->flags);
-	return 0;
-}
-
-static void ns_close(struct atm_vcc *vcc)
-{
-	vc_map *vc;
-	ns_dev *card;
-	u32 data;
-	int i;
-
-	vc = vcc->dev_data;
-	card = vcc->dev->dev_data;
-	PRINTK("nicstar%d: closing vpi.vci %d.%d \n", card->index,
-	       (int)vcc->vpi, vcc->vci);
-
-	clear_bit(ATM_VF_READY, &vcc->flags);
-
-	if (vcc->qos.rxtp.traffic_class != ATM_NONE) {
-		u32 addr;
-		unsigned long flags;
-
-		addr =
-		    NS_RCT +
-		    (vcc->vpi << card->vcibits | vcc->vci) * NS_RCT_ENTRY_SIZE;
-		spin_lock_irqsave(&card->res_lock, flags);
-		while (CMD_BUSY(card)) ;
-		writel(NS_CMD_CLOSE_CONNECTION | addr << 2,
-		       card->membase + CMD);
-		spin_unlock_irqrestore(&card->res_lock, flags);
-
-		vc->rx = 0;
-		if (vc->rx_iov != NULL) {
-			struct sk_buff *iovb;
-			u32 stat;
-
-			stat = readl(card->membase + STAT);
-			card->sbfqc = ns_stat_sfbqc_get(stat);
-			card->lbfqc = ns_stat_lfbqc_get(stat);
-
-			PRINTK
-			    ("nicstar%d: closing a VC with pending rx buffers.\n",
-			     card->index);
-			iovb = vc->rx_iov;
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			NS_PRV_IOVCNT(iovb) = 0;
-			spin_lock_irqsave(&card->int_lock, flags);
-			recycle_iov_buf(card, iovb);
-			spin_unlock_irqrestore(&card->int_lock, flags);
-			vc->rx_iov = NULL;
-		}
-	}
-
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		vc->tx = 0;
-	}
-
-	if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-		unsigned long flags;
-		ns_scqe *scqep;
-		scq_info *scq;
-
-		scq = vc->scq;
-
-		for (;;) {
-			spin_lock_irqsave(&scq->lock, flags);
-			scqep = scq->next;
-			if (scqep == scq->base)
-				scqep = scq->last;
-			else
-				scqep--;
-			if (scqep == scq->tail) {
-				spin_unlock_irqrestore(&scq->lock, flags);
-				break;
-			}
-			/* If the last entry is not a TSR, place one in the SCQ in order to
-			   be able to completely drain it and then close. */
-			if (!ns_scqe_is_tsr(scqep) && scq->tail != scq->next) {
-				ns_scqe tsr;
-				u32 scdi, scqi;
-				u32 data;
-				int index;
-
-				tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);
-				scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;
-				scqi = scq->next - scq->base;
-				tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);
-				tsr.word_3 = 0x00000000;
-				tsr.word_4 = 0x00000000;
-				*scq->next = tsr;
-				index = (int)scqi;
-				scq->skb[index] = NULL;
-				if (scq->next == scq->last)
-					scq->next = scq->base;
-				else
-					scq->next++;
-				data = scq_virt_to_bus(scq, scq->next);
-				ns_write_sram(card, scq->scd, &data, 1);
-			}
-			spin_unlock_irqrestore(&scq->lock, flags);
-			schedule();
-		}
-
-		/* Free all TST entries */
-		data = NS_TST_OPCODE_VARIABLE;
-		for (i = 0; i < NS_TST_NUM_ENTRIES; i++) {
-			if (card->tste2vc[i] == vc) {
-				ns_write_sram(card, card->tst_addr + i, &data,
-					      1);
-				card->tste2vc[i] = NULL;
-				card->tst_free_entries++;
-			}
-		}
-
-		card->scd2vc[(vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE] = NULL;
-		free_scq(card, vc->scq, vcc);
-	}
-
-	/* remove all references to vcc before deleting it */
-	if (vcc->qos.txtp.traffic_class != ATM_NONE) {
-		unsigned long flags;
-		scq_info *scq = card->scq0;
-
-		spin_lock_irqsave(&scq->lock, flags);
-
-		for (i = 0; i < scq->num_entries; i++) {
-			if (scq->skb[i] && ATM_SKB(scq->skb[i])->vcc == vcc) {
-				ATM_SKB(scq->skb[i])->vcc = NULL;
-				atm_return(vcc, scq->skb[i]->truesize);
-				PRINTK
-				    ("nicstar: deleted pending vcc mapping\n");
-			}
-		}
-
-		spin_unlock_irqrestore(&scq->lock, flags);
-	}
-
-	vcc->dev_data = NULL;
-	clear_bit(ATM_VF_PARTIAL, &vcc->flags);
-	clear_bit(ATM_VF_ADDR, &vcc->flags);
-
-#ifdef RX_DEBUG
-	{
-		u32 stat, cfg;
-		stat = readl(card->membase + STAT);
-		cfg = readl(card->membase + CFG);
-		printk("STAT = 0x%08X  CFG = 0x%08X  \n", stat, cfg);
-		printk
-		    ("TSQ: base = 0x%p  next = 0x%p  last = 0x%p  TSQT = 0x%08X \n",
-		     card->tsq.base, card->tsq.next,
-		     card->tsq.last, readl(card->membase + TSQT));
-		printk
-		    ("RSQ: base = 0x%p  next = 0x%p  last = 0x%p  RSQT = 0x%08X \n",
-		     card->rsq.base, card->rsq.next,
-		     card->rsq.last, readl(card->membase + RSQT));
-		printk("Empty free buffer queue interrupt %s \n",
-		       card->efbie ? "enabled" : "disabled");
-		printk("SBCNT = %d  count = %d   LBCNT = %d count = %d \n",
-		       ns_stat_sfbqc_get(stat), card->sbpool.count,
-		       ns_stat_lfbqc_get(stat), card->lbpool.count);
-		printk("hbpool.count = %d  iovpool.count = %d \n",
-		       card->hbpool.count, card->iovpool.count);
-	}
-#endif /* RX_DEBUG */
-}
-
-static void fill_tst(ns_dev * card, int n, vc_map * vc)
-{
-	u32 new_tst;
-	unsigned long cl;
-	int e, r;
-	u32 data;
-
-	/* It would be very complicated to keep the two TSTs synchronized while
-	   assuring that writes are only made to the inactive TST. So, for now I
-	   will use only one TST. If problems occur, I will change this again */
-
-	new_tst = card->tst_addr;
-
-	/* Fill procedure */
-
-	for (e = 0; e < NS_TST_NUM_ENTRIES; e++) {
-		if (card->tste2vc[e] == NULL)
-			break;
-	}
-	if (e == NS_TST_NUM_ENTRIES) {
-		printk("nicstar%d: No free TST entries found. \n", card->index);
-		return;
-	}
-
-	r = n;
-	cl = NS_TST_NUM_ENTRIES;
-	data = ns_tste_make(NS_TST_OPCODE_FIXED, vc->cbr_scd);
-
-	while (r > 0) {
-		if (cl >= NS_TST_NUM_ENTRIES && card->tste2vc[e] == NULL) {
-			card->tste2vc[e] = vc;
-			ns_write_sram(card, new_tst + e, &data, 1);
-			cl -= NS_TST_NUM_ENTRIES;
-			r--;
-		}
-
-		if (++e == NS_TST_NUM_ENTRIES) {
-			e = 0;
-		}
-		cl += n;
-	}
-
-	/* End of fill procedure */
-
-	data = ns_tste_make(NS_TST_OPCODE_END, new_tst);
-	ns_write_sram(card, new_tst + NS_TST_NUM_ENTRIES, &data, 1);
-	ns_write_sram(card, card->tst_addr + NS_TST_NUM_ENTRIES, &data, 1);
-	card->tst_addr = new_tst;
-}
-
-static int _ns_send(struct atm_vcc *vcc, struct sk_buff *skb, bool may_sleep)
-{
-	ns_dev *card;
-	vc_map *vc;
-	scq_info *scq;
-	unsigned long buflen;
-	ns_scqe scqe;
-	u32 flags;		/* TBD flags, not CPU flags */
-
-	card = vcc->dev->dev_data;
-	TXPRINTK("nicstar%d: ns_send() called.\n", card->index);
-	if ((vc = (vc_map *) vcc->dev_data) == NULL) {
-		printk("nicstar%d: vcc->dev_data == NULL on ns_send().\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (!vc->tx) {
-		printk("nicstar%d: Trying to transmit on a non-tx VC.\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (vcc->qos.aal != ATM_AAL5 && vcc->qos.aal != ATM_AAL0) {
-		printk("nicstar%d: Only AAL0 and AAL5 are supported.\n",
-		       card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	if (skb_shinfo(skb)->nr_frags != 0) {
-		printk("nicstar%d: No scatter-gather yet.\n", card->index);
-		atomic_inc(&vcc->stats->tx_err);
-		dev_kfree_skb_any(skb);
-		return -EINVAL;
-	}
-
-	ATM_SKB(skb)->vcc = vcc;
-
-	NS_PRV_DMA(skb) = dma_map_single(&card->pcidev->dev, skb->data,
-					 skb->len, DMA_TO_DEVICE);
-
-	if (vcc->qos.aal == ATM_AAL5) {
-		buflen = (skb->len + 47 + 8) / 48 * 48;	/* Multiple of 48 */
-		flags = NS_TBD_AAL5;
-		scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb));
-		scqe.word_3 = cpu_to_le32(skb->len);
-		scqe.word_4 =
-		    ns_tbd_mkword_4(0, (u32) vcc->vpi, (u32) vcc->vci, 0,
-				    ATM_SKB(skb)->
-				    atm_options & ATM_ATMOPT_CLP ? 1 : 0);
-		flags |= NS_TBD_EOPDU;
-	} else {		/* (vcc->qos.aal == ATM_AAL0) */
-
-		buflen = ATM_CELL_PAYLOAD;	/* i.e., 48 bytes */
-		flags = NS_TBD_AAL0;
-		scqe.word_2 = cpu_to_le32(NS_PRV_DMA(skb) + NS_AAL0_HEADER);
-		scqe.word_3 = cpu_to_le32(0x00000000);
-		if (*skb->data & 0x02)	/* Payload type 1 - end of pdu */
-			flags |= NS_TBD_EOPDU;
-		scqe.word_4 =
-		    cpu_to_le32(*((u32 *) skb->data) & ~NS_TBD_VC_MASK);
-		/* Force the VPI/VCI to be the same as in VCC struct */
-		scqe.word_4 |=
-		    cpu_to_le32((((u32) vcc->
-				  vpi) << NS_TBD_VPI_SHIFT | ((u32) vcc->
-							      vci) <<
-				 NS_TBD_VCI_SHIFT) & NS_TBD_VC_MASK);
-	}
-
-	if (vcc->qos.txtp.traffic_class == ATM_CBR) {
-		scqe.word_1 = ns_tbd_mkword_1_novbr(flags, (u32) buflen);
-		scq = ((vc_map *) vcc->dev_data)->scq;
-	} else {
-		scqe.word_1 =
-		    ns_tbd_mkword_1(flags, (u32) 1, (u32) 1, (u32) buflen);
-		scq = card->scq0;
-	}
-
-	if (push_scqe(card, vc, scq, &scqe, skb, may_sleep) != 0) {
-		atomic_inc(&vcc->stats->tx_err);
-		dma_unmap_single(&card->pcidev->dev, NS_PRV_DMA(skb), skb->len,
-				 DMA_TO_DEVICE);
-		dev_kfree_skb_any(skb);
-		return -EIO;
-	}
-	atomic_inc(&vcc->stats->tx);
-
-	return 0;
-}
-
-static int ns_send(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return _ns_send(vcc, skb, true);
-}
-
-static int ns_send_bh(struct atm_vcc *vcc, struct sk_buff *skb)
-{
-	return _ns_send(vcc, skb, false);
-}
-
-static int push_scqe(ns_dev * card, vc_map * vc, scq_info * scq, ns_scqe * tbd,
-		     struct sk_buff *skb, bool may_sleep)
-{
-	unsigned long flags;
-	ns_scqe tsr;
-	u32 scdi, scqi;
-	int scq_is_vbr;
-	u32 data;
-	int index;
-
-	spin_lock_irqsave(&scq->lock, flags);
-	while (scq->tail == scq->next) {
-		if (!may_sleep) {
-			spin_unlock_irqrestore(&scq->lock, flags);
-			printk("nicstar%d: Error pushing TBD.\n", card->index);
-			return 1;
-		}
-
-		scq->full = 1;
-		wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,
-							  scq->tail != scq->next,
-							  scq->lock,
-							  SCQFULL_TIMEOUT);
-
-		if (scq->full) {
-			spin_unlock_irqrestore(&scq->lock, flags);
-			printk("nicstar%d: Timeout pushing TBD.\n",
-			       card->index);
-			return 1;
-		}
-	}
-	*scq->next = *tbd;
-	index = (int)(scq->next - scq->base);
-	scq->skb[index] = skb;
-	XPRINTK("nicstar%d: sending skb at 0x%p (pos %d).\n",
-		card->index, skb, index);
-	XPRINTK("nicstar%d: TBD written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
-		card->index, le32_to_cpu(tbd->word_1), le32_to_cpu(tbd->word_2),
-		le32_to_cpu(tbd->word_3), le32_to_cpu(tbd->word_4),
-		scq->next);
-	if (scq->next == scq->last)
-		scq->next = scq->base;
-	else
-		scq->next++;
-
-	vc->tbd_count++;
-	if (scq->num_entries == VBR_SCQ_NUM_ENTRIES) {
-		scq->tbd_count++;
-		scq_is_vbr = 1;
-	} else
-		scq_is_vbr = 0;
-
-	if (vc->tbd_count >= MAX_TBD_PER_VC
-	    || scq->tbd_count >= MAX_TBD_PER_SCQ) {
-		int has_run = 0;
-
-		while (scq->tail == scq->next) {
-			if (!may_sleep) {
-				data = scq_virt_to_bus(scq, scq->next);
-				ns_write_sram(card, scq->scd, &data, 1);
-				spin_unlock_irqrestore(&scq->lock, flags);
-				printk("nicstar%d: Error pushing TSR.\n",
-				       card->index);
-				return 0;
-			}
-
-			scq->full = 1;
-			if (has_run++)
-				break;
-			wait_event_interruptible_lock_irq_timeout(scq->scqfull_waitq,
-								  scq->tail != scq->next,
-								  scq->lock,
-								  SCQFULL_TIMEOUT);
-		}
-
-		if (!scq->full) {
-			tsr.word_1 = ns_tsr_mkword_1(NS_TSR_INTENABLE);
-			if (scq_is_vbr)
-				scdi = NS_TSR_SCDISVBR;
-			else
-				scdi = (vc->cbr_scd - NS_FRSCD) / NS_FRSCD_SIZE;
-			scqi = scq->next - scq->base;
-			tsr.word_2 = ns_tsr_mkword_2(scdi, scqi);
-			tsr.word_3 = 0x00000000;
-			tsr.word_4 = 0x00000000;
-
-			*scq->next = tsr;
-			index = (int)scqi;
-			scq->skb[index] = NULL;
-			XPRINTK
-			    ("nicstar%d: TSR written:\n0x%x\n0x%x\n0x%x\n0x%x\n at 0x%p.\n",
-			     card->index, le32_to_cpu(tsr.word_1),
-			     le32_to_cpu(tsr.word_2), le32_to_cpu(tsr.word_3),
-			     le32_to_cpu(tsr.word_4), scq->next);
-			if (scq->next == scq->last)
-				scq->next = scq->base;
-			else
-				scq->next++;
-			vc->tbd_count = 0;
-			scq->tbd_count = 0;
-		} else
-			PRINTK("nicstar%d: Timeout pushing TSR.\n",
-			       card->index);
-	}
-	data = scq_virt_to_bus(scq, scq->next);
-	ns_write_sram(card, scq->scd, &data, 1);
-
-	spin_unlock_irqrestore(&scq->lock, flags);
-
-	return 0;
-}
-
-static void process_tsq(ns_dev * card)
-{
-	u32 scdi;
-	scq_info *scq;
-	ns_tsi *previous = NULL, *one_ahead, *two_ahead;
-	int serviced_entries;	/* flag indicating at least on entry was serviced */
-
-	serviced_entries = 0;
-
-	if (card->tsq.next == card->tsq.last)
-		one_ahead = card->tsq.base;
-	else
-		one_ahead = card->tsq.next + 1;
-
-	if (one_ahead == card->tsq.last)
-		two_ahead = card->tsq.base;
-	else
-		two_ahead = one_ahead + 1;
-
-	while (!ns_tsi_isempty(card->tsq.next) || !ns_tsi_isempty(one_ahead) ||
-	       !ns_tsi_isempty(two_ahead))
-		/* At most two empty, as stated in the 77201 errata */
-	{
-		serviced_entries = 1;
-
-		/* Skip the one or two possible empty entries */
-		while (ns_tsi_isempty(card->tsq.next)) {
-			if (card->tsq.next == card->tsq.last)
-				card->tsq.next = card->tsq.base;
-			else
-				card->tsq.next++;
-		}
-
-		if (!ns_tsi_tmrof(card->tsq.next)) {
-			scdi = ns_tsi_getscdindex(card->tsq.next);
-			if (scdi == NS_TSI_SCDISVBR)
-				scq = card->scq0;
-			else {
-				if (card->scd2vc[scdi] == NULL) {
-					printk
-					    ("nicstar%d: could not find VC from SCD index.\n",
-					     card->index);
-					ns_tsi_init(card->tsq.next);
-					return;
-				}
-				scq = card->scd2vc[scdi]->scq;
-			}
-			drain_scq(card, scq, ns_tsi_getscqpos(card->tsq.next));
-			scq->full = 0;
-			wake_up_interruptible(&(scq->scqfull_waitq));
-		}
-
-		ns_tsi_init(card->tsq.next);
-		previous = card->tsq.next;
-		if (card->tsq.next == card->tsq.last)
-			card->tsq.next = card->tsq.base;
-		else
-			card->tsq.next++;
-
-		if (card->tsq.next == card->tsq.last)
-			one_ahead = card->tsq.base;
-		else
-			one_ahead = card->tsq.next + 1;
-
-		if (one_ahead == card->tsq.last)
-			two_ahead = card->tsq.base;
-		else
-			two_ahead = one_ahead + 1;
-	}
-
-	if (serviced_entries)
-		writel(PTR_DIFF(previous, card->tsq.base),
-		       card->membase + TSQH);
-}
-
-static void drain_scq(ns_dev * card, scq_info * scq, int pos)
-{
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	int i;
-	unsigned long flags;
-
-	XPRINTK("nicstar%d: drain_scq() called, scq at 0x%p, pos %d.\n",
-		card->index, scq, pos);
-	if (pos >= scq->num_entries) {
-		printk("nicstar%d: Bad index on drain_scq().\n", card->index);
-		return;
-	}
-
-	spin_lock_irqsave(&scq->lock, flags);
-	i = (int)(scq->tail - scq->base);
-	if (++i == scq->num_entries)
-		i = 0;
-	while (i != pos) {
-		skb = scq->skb[i];
-		XPRINTK("nicstar%d: freeing skb at 0x%p (index %d).\n",
-			card->index, skb, i);
-		if (skb != NULL) {
-			dma_unmap_single(&card->pcidev->dev,
-					 NS_PRV_DMA(skb),
-					 skb->len,
-					 DMA_TO_DEVICE);
-			vcc = ATM_SKB(skb)->vcc;
-			if (vcc && vcc->pop != NULL) {
-				vcc->pop(vcc, skb);
-			} else {
-				dev_kfree_skb_irq(skb);
-			}
-			scq->skb[i] = NULL;
-		}
-		if (++i == scq->num_entries)
-			i = 0;
-	}
-	scq->tail = scq->base + pos;
-	spin_unlock_irqrestore(&scq->lock, flags);
-}
-
-static void process_rsq(ns_dev * card)
-{
-	ns_rsqe *previous;
-
-	if (!ns_rsqe_valid(card->rsq.next))
-		return;
-	do {
-		dequeue_rx(card, card->rsq.next);
-		ns_rsqe_init(card->rsq.next);
-		previous = card->rsq.next;
-		if (card->rsq.next == card->rsq.last)
-			card->rsq.next = card->rsq.base;
-		else
-			card->rsq.next++;
-	} while (ns_rsqe_valid(card->rsq.next));
-	writel(PTR_DIFF(previous, card->rsq.base), card->membase + RSQH);
-}
-
-static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe)
-{
-	u32 vpi, vci;
-	vc_map *vc;
-	struct sk_buff *iovb;
-	struct iovec *iov;
-	struct atm_vcc *vcc;
-	struct sk_buff *skb;
-	unsigned short aal5_len;
-	int len;
-	u32 stat;
-	u32 id;
-
-	stat = readl(card->membase + STAT);
-	card->sbfqc = ns_stat_sfbqc_get(stat);
-	card->lbfqc = ns_stat_lfbqc_get(stat);
-
-	id = le32_to_cpu(rsqe->buffer_handle);
-	skb = idr_remove(&card->idr, id);
-	if (!skb) {
-		RXPRINTK(KERN_ERR
-			 "nicstar%d: skb not found!\n", card->index);
-		return;
-	}
-	dma_sync_single_for_cpu(&card->pcidev->dev,
-				NS_PRV_DMA(skb),
-				(NS_PRV_BUFTYPE(skb) == BUF_SM
-				 ? NS_SMSKBSIZE : NS_LGSKBSIZE),
-				DMA_FROM_DEVICE);
-	dma_unmap_single(&card->pcidev->dev,
-			 NS_PRV_DMA(skb),
-			 (NS_PRV_BUFTYPE(skb) == BUF_SM
-			  ? NS_SMSKBSIZE : NS_LGSKBSIZE),
-			 DMA_FROM_DEVICE);
-	vpi = ns_rsqe_vpi(rsqe);
-	vci = ns_rsqe_vci(rsqe);
-	if (vpi >= 1UL << card->vpibits || vci >= 1UL << card->vcibits) {
-		printk("nicstar%d: SDU received for out-of-range vc %d.%d.\n",
-		       card->index, vpi, vci);
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	vc = &(card->vcmap[vpi << card->vcibits | vci]);
-	if (!vc->rx) {
-		RXPRINTK("nicstar%d: SDU received on non-rx vc %d.%d.\n",
-			 card->index, vpi, vci);
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	vcc = vc->rx_vcc;
-
-	if (vcc->qos.aal == ATM_AAL0) {
-		struct sk_buff *sb;
-		unsigned char *cell;
-		int i;
-
-		cell = skb->data;
-		for (i = ns_rsqe_cellcount(rsqe); i; i--) {
-			sb = dev_alloc_skb(NS_SMSKBSIZE);
-			if (!sb) {
-				printk
-				    ("nicstar%d: Can't allocate buffers for aal0.\n",
-				     card->index);
-				atomic_add(i, &vcc->stats->rx_drop);
-				break;
-			}
-			if (!atm_charge(vcc, sb->truesize)) {
-				RXPRINTK
-				    ("nicstar%d: atm_charge() dropped aal0 packets.\n",
-				     card->index);
-				atomic_add(i - 1, &vcc->stats->rx_drop);	/* already increased by 1 */
-				dev_kfree_skb_any(sb);
-				break;
-			}
-			/* Rebuild the header */
-			*((u32 *) sb->data) = le32_to_cpu(rsqe->word_1) << 4 |
-			    (ns_rsqe_clp(rsqe) ? 0x00000001 : 0x00000000);
-			if (i == 1 && ns_rsqe_eopdu(rsqe))
-				*((u32 *) sb->data) |= 0x00000002;
-			skb_put(sb, NS_AAL0_HEADER);
-			memcpy(skb_tail_pointer(sb), cell, ATM_CELL_PAYLOAD);
-			skb_put(sb, ATM_CELL_PAYLOAD);
-			ATM_SKB(sb)->vcc = vcc;
-			__net_timestamp(sb);
-			vcc->push(vcc, sb);
-			atomic_inc(&vcc->stats->rx);
-			cell += ATM_CELL_PAYLOAD;
-		}
-
-		recycle_rx_buf(card, skb);
-		return;
-	}
-
-	/* To reach this point, the AAL layer can only be AAL5 */
-
-	if ((iovb = vc->rx_iov) == NULL) {
-		iovb = skb_dequeue(&(card->iovpool.queue));
-		if (iovb == NULL) {	/* No buffers in the queue */
-			iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC);
-			if (iovb == NULL) {
-				printk("nicstar%d: Out of iovec buffers.\n",
-				       card->index);
-				atomic_inc(&vcc->stats->rx_drop);
-				recycle_rx_buf(card, skb);
-				return;
-			}
-			NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-		} else if (--card->iovpool.count < card->iovnr.min) {
-			struct sk_buff *new_iovb;
-			if ((new_iovb =
-			     alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL) {
-				NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-				skb_queue_tail(&card->iovpool.queue, new_iovb);
-				card->iovpool.count++;
-			}
-		}
-		vc->rx_iov = iovb;
-		NS_PRV_IOVCNT(iovb) = 0;
-		iovb->len = 0;
-		iovb->data = iovb->head;
-		skb_reset_tail_pointer(iovb);
-		/* IMPORTANT: a pointer to the sk_buff containing the small or large
-		   buffer is stored as iovec base, NOT a pointer to the
-		   small or large buffer itself. */
-	} else if (NS_PRV_IOVCNT(iovb) >= NS_MAX_IOVECS) {
-		printk("nicstar%d: received too big AAL5 SDU.\n", card->index);
-		atomic_inc(&vcc->stats->rx_err);
-		recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-				      NS_MAX_IOVECS);
-		NS_PRV_IOVCNT(iovb) = 0;
-		iovb->len = 0;
-		iovb->data = iovb->head;
-		skb_reset_tail_pointer(iovb);
-	}
-	iov = &((struct iovec *)iovb->data)[NS_PRV_IOVCNT(iovb)++];
-	iov->iov_base = (void *)skb;
-	iov->iov_len = ns_rsqe_cellcount(rsqe) * 48;
-	iovb->len += iov->iov_len;
-
-#ifdef EXTRA_DEBUG
-	if (NS_PRV_IOVCNT(iovb) == 1) {
-		if (NS_PRV_BUFTYPE(skb) != BUF_SM) {
-			printk
-			    ("nicstar%d: Expected a small buffer, and this is not one.\n",
-			     card->index);
-			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_rx_buf(card, skb);
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-	} else {		/* NS_PRV_IOVCNT(iovb) >= 2 */
-
-		if (NS_PRV_BUFTYPE(skb) != BUF_LG) {
-			printk
-			    ("nicstar%d: Expected a large buffer, and this is not one.\n",
-			     card->index);
-			which_list(card, skb);
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-	}
-#endif /* EXTRA_DEBUG */
-
-	if (ns_rsqe_eopdu(rsqe)) {
-		/* This works correctly regardless of the endianness of the host */
-		unsigned char *L1L2 = (unsigned char *)
-						(skb->data + iov->iov_len - 6);
-		aal5_len = L1L2[0] << 8 | L1L2[1];
-		len = (aal5_len == 0x0000) ? 0x10000 : aal5_len;
-		if (ns_rsqe_crcerr(rsqe) ||
-		    len + 8 > iovb->len || len + (47 + 8) < iovb->len) {
-			printk("nicstar%d: AAL5 CRC error", card->index);
-			if (len + 8 > iovb->len || len + (47 + 8) < iovb->len)
-				printk(" - PDU size mismatch.\n");
-			else
-				printk(".\n");
-			atomic_inc(&vcc->stats->rx_err);
-			recycle_iovec_rx_bufs(card, (struct iovec *)iovb->data,
-					      NS_PRV_IOVCNT(iovb));
-			vc->rx_iov = NULL;
-			recycle_iov_buf(card, iovb);
-			return;
-		}
-
-		/* By this point we (hopefully) have a complete SDU without errors. */
-
-		if (NS_PRV_IOVCNT(iovb) == 1) {	/* Just a small buffer */
-			/* skb points to a small buffer */
-			if (!atm_charge(vcc, skb->truesize)) {
-				push_rxbufs(card, skb);
-				atomic_inc(&vcc->stats->rx_drop);
-			} else {
-				skb_put(skb, len);
-				dequeue_sm_buf(card, skb);
-				ATM_SKB(skb)->vcc = vcc;
-				__net_timestamp(skb);
-				vcc->push(vcc, skb);
-				atomic_inc(&vcc->stats->rx);
-			}
-		} else if (NS_PRV_IOVCNT(iovb) == 2) {	/* One small plus one large buffer */
-			struct sk_buff *sb;
-
-			sb = (struct sk_buff *)(iov - 1)->iov_base;
-			/* skb points to a large buffer */
-
-			if (len <= NS_SMBUFSIZE) {
-				if (!atm_charge(vcc, sb->truesize)) {
-					push_rxbufs(card, sb);
-					atomic_inc(&vcc->stats->rx_drop);
-				} else {
-					skb_put(sb, len);
-					dequeue_sm_buf(card, sb);
-					ATM_SKB(sb)->vcc = vcc;
-					__net_timestamp(sb);
-					vcc->push(vcc, sb);
-					atomic_inc(&vcc->stats->rx);
-				}
-
-				push_rxbufs(card, skb);
-
-			} else {	/* len > NS_SMBUFSIZE, the usual case */
-
-				if (!atm_charge(vcc, skb->truesize)) {
-					push_rxbufs(card, skb);
-					atomic_inc(&vcc->stats->rx_drop);
-				} else {
-					dequeue_lg_buf(card, skb);
-					skb_push(skb, NS_SMBUFSIZE);
-					skb_copy_from_linear_data(sb, skb->data,
-								  NS_SMBUFSIZE);
-					skb_put(skb, len - NS_SMBUFSIZE);
-					ATM_SKB(skb)->vcc = vcc;
-					__net_timestamp(skb);
-					vcc->push(vcc, skb);
-					atomic_inc(&vcc->stats->rx);
-				}
-
-				push_rxbufs(card, sb);
-
-			}
-
-		} else {	/* Must push a huge buffer */
-
-			struct sk_buff *hb, *sb, *lb;
-			int remaining, tocopy;
-			int j;
-
-			hb = skb_dequeue(&(card->hbpool.queue));
-			if (hb == NULL) {	/* No buffers in the queue */
-
-				hb = dev_alloc_skb(NS_HBUFSIZE);
-				if (hb == NULL) {
-					printk
-					    ("nicstar%d: Out of huge buffers.\n",
-					     card->index);
-					atomic_inc(&vcc->stats->rx_drop);
-					recycle_iovec_rx_bufs(card,
-							      (struct iovec *)
-							      iovb->data,
-							      NS_PRV_IOVCNT(iovb));
-					vc->rx_iov = NULL;
-					recycle_iov_buf(card, iovb);
-					return;
-				} else if (card->hbpool.count < card->hbnr.min) {
-					struct sk_buff *new_hb;
-					if ((new_hb =
-					     dev_alloc_skb(NS_HBUFSIZE)) !=
-					    NULL) {
-						skb_queue_tail(&card->hbpool.
-							       queue, new_hb);
-						card->hbpool.count++;
-					}
-				}
-				NS_PRV_BUFTYPE(hb) = BUF_NONE;
-			} else if (--card->hbpool.count < card->hbnr.min) {
-				struct sk_buff *new_hb;
-				if ((new_hb =
-				     dev_alloc_skb(NS_HBUFSIZE)) != NULL) {
-					NS_PRV_BUFTYPE(new_hb) = BUF_NONE;
-					skb_queue_tail(&card->hbpool.queue,
-						       new_hb);
-					card->hbpool.count++;
-				}
-				if (card->hbpool.count < card->hbnr.min) {
-					if ((new_hb =
-					     dev_alloc_skb(NS_HBUFSIZE)) !=
-					    NULL) {
-						NS_PRV_BUFTYPE(new_hb) =
-						    BUF_NONE;
-						skb_queue_tail(&card->hbpool.
-							       queue, new_hb);
-						card->hbpool.count++;
-					}
-				}
-			}
-
-			iov = (struct iovec *)iovb->data;
-
-			if (!atm_charge(vcc, hb->truesize)) {
-				recycle_iovec_rx_bufs(card, iov,
-						      NS_PRV_IOVCNT(iovb));
-				if (card->hbpool.count < card->hbnr.max) {
-					skb_queue_tail(&card->hbpool.queue, hb);
-					card->hbpool.count++;
-				} else
-					dev_kfree_skb_any(hb);
-				atomic_inc(&vcc->stats->rx_drop);
-			} else {
-				/* Copy the small buffer to the huge buffer */
-				sb = (struct sk_buff *)iov->iov_base;
-				skb_copy_from_linear_data(sb, hb->data,
-							  iov->iov_len);
-				skb_put(hb, iov->iov_len);
-				remaining = len - iov->iov_len;
-				iov++;
-				/* Free the small buffer */
-				push_rxbufs(card, sb);
-
-				/* Copy all large buffers to the huge buffer and free them */
-				for (j = 1; j < NS_PRV_IOVCNT(iovb); j++) {
-					lb = (struct sk_buff *)iov->iov_base;
-					tocopy =
-					    min_t(int, remaining, iov->iov_len);
-					skb_copy_from_linear_data(lb,
-								  skb_tail_pointer
-								  (hb), tocopy);
-					skb_put(hb, tocopy);
-					iov++;
-					remaining -= tocopy;
-					push_rxbufs(card, lb);
-				}
-#ifdef EXTRA_DEBUG
-				if (remaining != 0 || hb->len != len)
-					printk
-					    ("nicstar%d: Huge buffer len mismatch.\n",
-					     card->index);
-#endif /* EXTRA_DEBUG */
-				ATM_SKB(hb)->vcc = vcc;
-				__net_timestamp(hb);
-				vcc->push(vcc, hb);
-				atomic_inc(&vcc->stats->rx);
-			}
-		}
-
-		vc->rx_iov = NULL;
-		recycle_iov_buf(card, iovb);
-	}
-
-}
-
-static void recycle_rx_buf(ns_dev * card, struct sk_buff *skb)
-{
-	if (unlikely(NS_PRV_BUFTYPE(skb) == BUF_NONE)) {
-		printk("nicstar%d: What kind of rx buffer is this?\n",
-		       card->index);
-		dev_kfree_skb_any(skb);
-	} else
-		push_rxbufs(card, skb);
-}
-
-static void recycle_iovec_rx_bufs(ns_dev * card, struct iovec *iov, int count)
-{
-	while (count-- > 0)
-		recycle_rx_buf(card, (struct sk_buff *)(iov++)->iov_base);
-}
-
-static void recycle_iov_buf(ns_dev * card, struct sk_buff *iovb)
-{
-	if (card->iovpool.count < card->iovnr.max) {
-		skb_queue_tail(&card->iovpool.queue, iovb);
-		card->iovpool.count++;
-	} else
-		dev_kfree_skb_any(iovb);
-}
-
-static void dequeue_sm_buf(ns_dev * card, struct sk_buff *sb)
-{
-	skb_unlink(sb, &card->sbpool.queue);
-	if (card->sbfqc < card->sbnr.init) {
-		struct sk_buff *new_sb;
-		if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, new_sb);
-			skb_reserve(new_sb, NS_AAL0_HEADER);
-			push_rxbufs(card, new_sb);
-		}
-	}
-	if (card->sbfqc < card->sbnr.init)
-	{
-		struct sk_buff *new_sb;
-		if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_sb) = BUF_SM;
-			skb_queue_tail(&card->sbpool.queue, new_sb);
-			skb_reserve(new_sb, NS_AAL0_HEADER);
-			push_rxbufs(card, new_sb);
-		}
-	}
-}
-
-static void dequeue_lg_buf(ns_dev * card, struct sk_buff *lb)
-{
-	skb_unlink(lb, &card->lbpool.queue);
-	if (card->lbfqc < card->lbnr.init) {
-		struct sk_buff *new_lb;
-		if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, new_lb);
-			skb_reserve(new_lb, NS_SMBUFSIZE);
-			push_rxbufs(card, new_lb);
-		}
-	}
-	if (card->lbfqc < card->lbnr.init)
-	{
-		struct sk_buff *new_lb;
-		if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL) {
-			NS_PRV_BUFTYPE(new_lb) = BUF_LG;
-			skb_queue_tail(&card->lbpool.queue, new_lb);
-			skb_reserve(new_lb, NS_SMBUFSIZE);
-			push_rxbufs(card, new_lb);
-		}
-	}
-}
-
-static int ns_proc_read(struct atm_dev *dev, loff_t * pos, char *page)
-{
-	u32 stat;
-	ns_dev *card;
-	int left;
-
-	left = (int)*pos;
-	card = (ns_dev *) dev->dev_data;
-	stat = readl(card->membase + STAT);
-	if (!left--)
-		return sprintf(page, "Pool   count    min   init    max \n");
-	if (!left--)
-		return sprintf(page, "Small  %5d  %5d  %5d  %5d \n",
-			       ns_stat_sfbqc_get(stat), card->sbnr.min,
-			       card->sbnr.init, card->sbnr.max);
-	if (!left--)
-		return sprintf(page, "Large  %5d  %5d  %5d  %5d \n",
-			       ns_stat_lfbqc_get(stat), card->lbnr.min,
-			       card->lbnr.init, card->lbnr.max);
-	if (!left--)
-		return sprintf(page, "Huge   %5d  %5d  %5d  %5d \n",
-			       card->hbpool.count, card->hbnr.min,
-			       card->hbnr.init, card->hbnr.max);
-	if (!left--)
-		return sprintf(page, "Iovec  %5d  %5d  %5d  %5d \n",
-			       card->iovpool.count, card->iovnr.min,
-			       card->iovnr.init, card->iovnr.max);
-	if (!left--) {
-		int retval;
-		retval =
-		    sprintf(page, "Interrupt counter: %u \n", card->intcnt);
-		card->intcnt = 0;
-		return retval;
-	}
-#if 0
-	/* Dump 25.6 Mbps PHY registers */
-	/* Now there's a 25.6 Mbps PHY driver this code isn't needed. I left it
-	   here just in case it's needed for debugging. */
-	if (card->max_pcr == ATM_25_PCR && !left--) {
-		u32 phy_regs[4];
-		u32 i;
-
-		for (i = 0; i < 4; i++) {
-			while (CMD_BUSY(card)) ;
-			writel(NS_CMD_READ_UTILITY | 0x00000200 | i,
-			       card->membase + CMD);
-			while (CMD_BUSY(card)) ;
-			phy_regs[i] = readl(card->membase + DR0) & 0x000000FF;
-		}
-
-		return sprintf(page, "PHY regs: 0x%02X 0x%02X 0x%02X 0x%02X \n",
-			       phy_regs[0], phy_regs[1], phy_regs[2],
-			       phy_regs[3]);
-	}
-#endif /* 0 - Dump 25.6 Mbps PHY registers */
-#if 0
-	/* Dump TST */
-	if (left-- < NS_TST_NUM_ENTRIES) {
-		if (card->tste2vc[left + 1] == NULL)
-			return sprintf(page, "%5d - VBR/UBR \n", left + 1);
-		else
-			return sprintf(page, "%5d - %d %d \n", left + 1,
-				       card->tste2vc[left + 1]->tx_vcc->vpi,
-				       card->tste2vc[left + 1]->tx_vcc->vci);
-	}
-#endif /* 0 */
-	return 0;
-}
-
-static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user * arg)
-{
-	ns_dev *card;
-	pool_levels pl;
-	long btype;
-	unsigned long flags;
-
-	card = dev->dev_data;
-	switch (cmd) {
-	case NS_GETPSTAT:
-		if (get_user
-		    (pl.buftype, &((pool_levels __user *) arg)->buftype))
-			return -EFAULT;
-		switch (pl.buftype) {
-		case NS_BUFTYPE_SMALL:
-			pl.count =
-			    ns_stat_sfbqc_get(readl(card->membase + STAT));
-			pl.level.min = card->sbnr.min;
-			pl.level.init = card->sbnr.init;
-			pl.level.max = card->sbnr.max;
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			pl.count =
-			    ns_stat_lfbqc_get(readl(card->membase + STAT));
-			pl.level.min = card->lbnr.min;
-			pl.level.init = card->lbnr.init;
-			pl.level.max = card->lbnr.max;
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			pl.count = card->hbpool.count;
-			pl.level.min = card->hbnr.min;
-			pl.level.init = card->hbnr.init;
-			pl.level.max = card->hbnr.max;
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			pl.count = card->iovpool.count;
-			pl.level.min = card->iovnr.min;
-			pl.level.init = card->iovnr.init;
-			pl.level.max = card->iovnr.max;
-			break;
-
-		default:
-			return -ENOIOCTLCMD;
-
-		}
-		if (!copy_to_user((pool_levels __user *) arg, &pl, sizeof(pl)))
-			return (sizeof(pl));
-		else
-			return -EFAULT;
-
-	case NS_SETBUFLEV:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		if (copy_from_user(&pl, (pool_levels __user *) arg, sizeof(pl)))
-			return -EFAULT;
-		if (pl.level.min >= pl.level.init
-		    || pl.level.init >= pl.level.max)
-			return -EINVAL;
-		if (pl.level.min == 0)
-			return -EINVAL;
-		switch (pl.buftype) {
-		case NS_BUFTYPE_SMALL:
-			if (pl.level.max > TOP_SB)
-				return -EINVAL;
-			card->sbnr.min = pl.level.min;
-			card->sbnr.init = pl.level.init;
-			card->sbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			if (pl.level.max > TOP_LB)
-				return -EINVAL;
-			card->lbnr.min = pl.level.min;
-			card->lbnr.init = pl.level.init;
-			card->lbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			if (pl.level.max > TOP_HB)
-				return -EINVAL;
-			card->hbnr.min = pl.level.min;
-			card->hbnr.init = pl.level.init;
-			card->hbnr.max = pl.level.max;
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			if (pl.level.max > TOP_IOVB)
-				return -EINVAL;
-			card->iovnr.min = pl.level.min;
-			card->iovnr.init = pl.level.init;
-			card->iovnr.max = pl.level.max;
-			break;
-
-		default:
-			return -EINVAL;
-
-		}
-		return 0;
-
-	case NS_ADJBUFLEV:
-		if (!capable(CAP_NET_ADMIN))
-			return -EPERM;
-		btype = (long)arg;	/* a long is the same size as a pointer or bigger */
-		switch (btype) {
-		case NS_BUFTYPE_SMALL:
-			while (card->sbfqc < card->sbnr.init) {
-				struct sk_buff *sb;
-
-				sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
-				if (sb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(sb) = BUF_SM;
-				skb_queue_tail(&card->sbpool.queue, sb);
-				skb_reserve(sb, NS_AAL0_HEADER);
-				push_rxbufs(card, sb);
-			}
-			break;
-
-		case NS_BUFTYPE_LARGE:
-			while (card->lbfqc < card->lbnr.init) {
-				struct sk_buff *lb;
-
-				lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
-				if (lb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(lb) = BUF_LG;
-				skb_queue_tail(&card->lbpool.queue, lb);
-				skb_reserve(lb, NS_SMBUFSIZE);
-				push_rxbufs(card, lb);
-			}
-			break;
-
-		case NS_BUFTYPE_HUGE:
-			while (card->hbpool.count > card->hbnr.init) {
-				struct sk_buff *hb;
-
-				spin_lock_irqsave(&card->int_lock, flags);
-				hb = skb_dequeue(&card->hbpool.queue);
-				card->hbpool.count--;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-				if (hb == NULL)
-					printk
-					    ("nicstar%d: huge buffer count inconsistent.\n",
-					     card->index);
-				else
-					dev_kfree_skb_any(hb);
-
-			}
-			while (card->hbpool.count < card->hbnr.init) {
-				struct sk_buff *hb;
-
-				hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
-				if (hb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(hb) = BUF_NONE;
-				spin_lock_irqsave(&card->int_lock, flags);
-				skb_queue_tail(&card->hbpool.queue, hb);
-				card->hbpool.count++;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-			}
-			break;
-
-		case NS_BUFTYPE_IOVEC:
-			while (card->iovpool.count > card->iovnr.init) {
-				struct sk_buff *iovb;
-
-				spin_lock_irqsave(&card->int_lock, flags);
-				iovb = skb_dequeue(&card->iovpool.queue);
-				card->iovpool.count--;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-				if (iovb == NULL)
-					printk
-					    ("nicstar%d: iovec buffer count inconsistent.\n",
-					     card->index);
-				else
-					dev_kfree_skb_any(iovb);
-
-			}
-			while (card->iovpool.count < card->iovnr.init) {
-				struct sk_buff *iovb;
-
-				iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
-				if (iovb == NULL)
-					return -ENOMEM;
-				NS_PRV_BUFTYPE(iovb) = BUF_NONE;
-				spin_lock_irqsave(&card->int_lock, flags);
-				skb_queue_tail(&card->iovpool.queue, iovb);
-				card->iovpool.count++;
-				spin_unlock_irqrestore(&card->int_lock, flags);
-			}
-			break;
-
-		default:
-			return -EINVAL;
-
-		}
-		return 0;
-
-	default:
-		if (dev->phy && dev->phy->ioctl) {
-			return dev->phy->ioctl(dev, cmd, arg);
-		} else {
-			printk("nicstar%d: %s == NULL \n", card->index,
-			       dev->phy ? "dev->phy->ioctl" : "dev->phy");
-			return -ENOIOCTLCMD;
-		}
-	}
-}
-
-#ifdef EXTRA_DEBUG
-static void which_list(ns_dev * card, struct sk_buff *skb)
-{
-	printk("skb buf_type: 0x%08x\n", NS_PRV_BUFTYPE(skb));
-}
-#endif /* EXTRA_DEBUG */
-
-static void ns_poll(struct timer_list *unused)
-{
-	int i;
-	ns_dev *card;
-	unsigned long flags;
-	u32 stat_r, stat_w;
-
-	PRINTK("nicstar: Entering ns_poll().\n");
-	for (i = 0; i < num_cards; i++) {
-		card = cards[i];
-		if (!spin_trylock_irqsave(&card->int_lock, flags)) {
-			/* Probably it isn't worth spinning */
-			continue;
-		}
-
-		stat_w = 0;
-		stat_r = readl(card->membase + STAT);
-		if (stat_r & NS_STAT_TSIF)
-			stat_w |= NS_STAT_TSIF;
-		if (stat_r & NS_STAT_EOPDU)
-			stat_w |= NS_STAT_EOPDU;
-
-		process_tsq(card);
-		process_rsq(card);
-
-		writel(stat_w, card->membase + STAT);
-		spin_unlock_irqrestore(&card->int_lock, flags);
-	}
-	mod_timer(&ns_timer, jiffies + NS_POLL_PERIOD);
-	PRINTK("nicstar: Leaving ns_poll().\n");
-}
-
-static void ns_phy_put(struct atm_dev *dev, unsigned char value,
-		       unsigned long addr)
-{
-	ns_dev *card;
-	unsigned long flags;
-
-	card = dev->dev_data;
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel((u32) value, card->membase + DR0);
-	writel(NS_CMD_WRITE_UTILITY | 0x00000200 | (addr & 0x000000FF),
-	       card->membase + CMD);
-	spin_unlock_irqrestore(&card->res_lock, flags);
-}
-
-static unsigned char ns_phy_get(struct atm_dev *dev, unsigned long addr)
-{
-	ns_dev *card;
-	unsigned long flags;
-	u32 data;
-
-	card = dev->dev_data;
-	spin_lock_irqsave(&card->res_lock, flags);
-	while (CMD_BUSY(card)) ;
-	writel(NS_CMD_READ_UTILITY | 0x00000200 | (addr & 0x000000FF),
-	       card->membase + CMD);
-	while (CMD_BUSY(card)) ;
-	data = readl(card->membase + DR0) & 0x000000FF;
-	spin_unlock_irqrestore(&card->res_lock, flags);
-	return (unsigned char)data;
-}
-
-module_init(nicstar_init);
-module_exit(nicstar_cleanup);
diff --git a/drivers/atm/nicstar.h b/drivers/atm/nicstar.h
deleted file mode 100644
index 1b7f1df..0000000
--- a/drivers/atm/nicstar.h
+++ /dev/null
@@ -1,759 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * nicstar.h
- *
- * Header file for the nicstar device driver.
- *
- * Author: Rui Prior (rprior@inescn.pt)
- * PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999
- *
- * (C) INESC 1998
- */
-
-#ifndef _LINUX_NICSTAR_H_
-#define _LINUX_NICSTAR_H_
-
-/* Includes */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/idr.h>
-#include <linux/uio.h>
-#include <linux/skbuff.h>
-#include <linux/atmdev.h>
-#include <linux/atm_nicstar.h>
-
-/* Options */
-
-#define NS_MAX_CARDS 4		/* Maximum number of NICStAR based cards
-				   controlled by the device driver. Must
-				   be <= 5 */
-
-#undef RCQ_SUPPORT		/* Do not define this for now */
-
-#define NS_TST_NUM_ENTRIES 2340	/* + 1 for return */
-#define NS_TST_RESERVED 340	/* N. entries reserved for UBR/ABR/VBR */
-
-#define NS_SMBUFSIZE 48		/* 48, 96, 240 or 2048 */
-#define NS_LGBUFSIZE 16384	/* 2048, 4096, 8192 or 16384 */
-#define NS_RSQSIZE 8192		/* 2048, 4096 or 8192 */
-#define NS_VPIBITS 2		/* 0, 1, 2, or 8 */
-
-#define NS_MAX_RCTSIZE 4096	/* Number of entries. 4096 or 16384.
-				   Define 4096 only if (all) your card(s)
-				   have 32K x 32bit SRAM, in which case
-				   setting this to 16384 will just waste a
-				   lot of memory.
-				   Setting this to 4096 for a card with
-				   128K x 32bit SRAM will limit the maximum
-				   VCI. */
-
-				/*#define NS_PCI_LATENCY 64*//* Must be a multiple of 32 */
-
-	/* Number of buffers initially allocated */
-#define NUM_SB 32		/* Must be even */
-#define NUM_LB 24		/* Must be even */
-#define NUM_HB 8		/* Pre-allocated huge buffers */
-#define NUM_IOVB 48		/* Iovec buffers */
-
-	/* Lower level for count of buffers */
-#define MIN_SB 8		/* Must be even */
-#define MIN_LB 8		/* Must be even */
-#define MIN_HB 6
-#define MIN_IOVB 8
-
-	/* Upper level for count of buffers */
-#define MAX_SB 64		/* Must be even, <= 508 */
-#define MAX_LB 48		/* Must be even, <= 508 */
-#define MAX_HB 10
-#define MAX_IOVB 80
-
-	/* These are the absolute maximum allowed for the ioctl() */
-#define TOP_SB 256		/* Must be even, <= 508 */
-#define TOP_LB 128		/* Must be even, <= 508 */
-#define TOP_HB 64
-#define TOP_IOVB 256
-
-#define MAX_TBD_PER_VC 1	/* Number of TBDs before a TSR */
-#define MAX_TBD_PER_SCQ 10	/* Only meaningful for variable rate SCQs */
-
-#undef ENABLE_TSQFIE
-
-#define SCQFULL_TIMEOUT (5 * HZ)
-
-#define NS_POLL_PERIOD (HZ)
-
-#define PCR_TOLERANCE (1.0001)
-
-/* ESI stuff */
-
-#define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C
-#define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6
-
-/* #defines */
-
-#define NS_IOREMAP_SIZE 4096
-
-/*
- * BUF_XX distinguish the Rx buffers depending on their (small/large) size.
- * BUG_SM and BUG_LG are both used by the driver and the device.
- * BUF_NONE is only used by the driver.
- */
-#define BUF_SM		0x00000000	/* These two are used for push_rxbufs() */
-#define BUF_LG		0x00000001	/* CMD, Write_FreeBufQ, LBUF bit */
-#define BUF_NONE 	0xffffffff	/* Software only: */
-
-#define NS_HBUFSIZE 65568	/* Size of max. AAL5 PDU */
-#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
-                       (NS_LGBUFSIZE - (NS_LGBUFSIZE % 48)))
-#define NS_IOVBUFSIZE (NS_MAX_IOVECS * (sizeof(struct iovec)))
-
-#define NS_SMBUFSIZE_USABLE (NS_SMBUFSIZE - NS_SMBUFSIZE % 48)
-#define NS_LGBUFSIZE_USABLE (NS_LGBUFSIZE - NS_LGBUFSIZE % 48)
-
-#define NS_AAL0_HEADER (ATM_AAL0_SDU - ATM_CELL_PAYLOAD)	/* 4 bytes */
-
-#define NS_SMSKBSIZE (NS_SMBUFSIZE + NS_AAL0_HEADER)
-#define NS_LGSKBSIZE (NS_SMBUFSIZE + NS_LGBUFSIZE)
-
-/* NICStAR structures located in host memory */
-
-/*
- * RSQ - Receive Status Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct ns_rsqe {
-	u32 word_1;
-	u32 buffer_handle;
-	u32 final_aal5_crc32;
-	u32 word_4;
-} ns_rsqe;
-
-#define ns_rsqe_vpi(ns_rsqep) \
-        ((le32_to_cpu((ns_rsqep)->word_1) & 0x00FF0000) >> 16)
-#define ns_rsqe_vci(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_1) & 0x0000FFFF)
-
-#define NS_RSQE_VALID      0x80000000
-#define NS_RSQE_NZGFC      0x00004000
-#define NS_RSQE_EOPDU      0x00002000
-#define NS_RSQE_BUFSIZE    0x00001000
-#define NS_RSQE_CONGESTION 0x00000800
-#define NS_RSQE_CLP        0x00000400
-#define NS_RSQE_CRCERR     0x00000200
-
-#define NS_RSQE_BUFSIZE_SM 0x00000000
-#define NS_RSQE_BUFSIZE_LG 0x00001000
-
-#define ns_rsqe_valid(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_VALID)
-#define ns_rsqe_nzgfc(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_NZGFC)
-#define ns_rsqe_eopdu(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_EOPDU)
-#define ns_rsqe_bufsize(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_BUFSIZE)
-#define ns_rsqe_congestion(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CONGESTION)
-#define ns_rsqe_clp(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CLP)
-#define ns_rsqe_crcerr(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CRCERR)
-
-#define ns_rsqe_cellcount(ns_rsqep) \
-        (le32_to_cpu((ns_rsqep)->word_4) & 0x000001FF)
-#define ns_rsqe_init(ns_rsqep) \
-        ((ns_rsqep)->word_4 = cpu_to_le32(0x00000000))
-
-#define NS_RSQ_NUM_ENTRIES (NS_RSQSIZE / 16)
-#define NS_RSQ_ALIGNMENT NS_RSQSIZE
-
-/*
- * RCQ - Raw Cell Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct cell_payload {
-	u32 word[12];
-} cell_payload;
-
-typedef struct ns_rcqe {
-	u32 word_1;
-	u32 word_2;
-	u32 word_3;
-	u32 word_4;
-	cell_payload payload;
-} ns_rcqe;
-
-#define NS_RCQE_SIZE 64		/* bytes */
-
-#define ns_rcqe_islast(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_2) != 0x00000000)
-#define ns_rcqe_cellheader(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_1))
-#define ns_rcqe_nextbufhandle(ns_rcqep) \
-        (le32_to_cpu((ns_rcqep)->word_2))
-
-/*
- * SCQ - Segmentation Channel Queue
- *
- * Written by the device driver, read by the NICStAR.
- */
-
-typedef struct ns_scqe {
-	u32 word_1;
-	u32 word_2;
-	u32 word_3;
-	u32 word_4;
-} ns_scqe;
-
-   /* NOTE: SCQ entries can be either a TBD (Transmit Buffer Descriptors)
-      or TSR (Transmit Status Requests) */
-
-#define NS_SCQE_TYPE_TBD 0x00000000
-#define NS_SCQE_TYPE_TSR 0x80000000
-
-#define NS_TBD_EOPDU 0x40000000
-#define NS_TBD_AAL0  0x00000000
-#define NS_TBD_AAL34 0x04000000
-#define NS_TBD_AAL5  0x08000000
-
-#define NS_TBD_VPI_MASK 0x0FF00000
-#define NS_TBD_VCI_MASK 0x000FFFF0
-#define NS_TBD_VC_MASK (NS_TBD_VPI_MASK | NS_TBD_VCI_MASK)
-
-#define NS_TBD_VPI_SHIFT 20
-#define NS_TBD_VCI_SHIFT 4
-
-#define ns_tbd_mkword_1(flags, m, n, buflen) \
-      (cpu_to_le32((flags) | (m) << 23 | (n) << 16 | (buflen)))
-#define ns_tbd_mkword_1_novbr(flags, buflen) \
-      (cpu_to_le32((flags) | (buflen) | 0x00810000))
-#define ns_tbd_mkword_3(control, pdulen) \
-      (cpu_to_le32((control) << 16 | (pdulen)))
-#define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \
-      (cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp)))
-
-#define NS_TSR_INTENABLE 0x20000000
-
-#define NS_TSR_SCDISVBR 0xFFFF	/* Use as scdi for VBR SCD */
-
-#define ns_tsr_mkword_1(flags) \
-        (cpu_to_le32(NS_SCQE_TYPE_TSR | (flags)))
-#define ns_tsr_mkword_2(scdi, scqi) \
-        (cpu_to_le32((scdi) << 16 | 0x00008000 | (scqi)))
-
-#define ns_scqe_is_tsr(ns_scqep) \
-        (le32_to_cpu((ns_scqep)->word_1) & NS_SCQE_TYPE_TSR)
-
-#define VBR_SCQ_NUM_ENTRIES 512
-#define VBR_SCQSIZE 8192
-#define CBR_SCQ_NUM_ENTRIES 64
-#define CBR_SCQSIZE 1024
-
-#define NS_SCQE_SIZE 16
-
-/*
- * TSQ - Transmit Status Queue
- *
- * Written by the NICStAR, read by the device driver.
- */
-
-typedef struct ns_tsi {
-	u32 word_1;
-	u32 word_2;
-} ns_tsi;
-
-   /* NOTE: The first word can be a status word copied from the TSR which
-      originated the TSI, or a timer overflow indicator. In this last
-      case, the value of the first word is all zeroes. */
-
-#define NS_TSI_EMPTY          0x80000000
-#define NS_TSI_TIMESTAMP_MASK 0x00FFFFFF
-
-#define ns_tsi_isempty(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_2) & NS_TSI_EMPTY)
-#define ns_tsi_gettimestamp(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_2) & NS_TSI_TIMESTAMP_MASK)
-
-#define ns_tsi_init(ns_tsip) \
-        ((ns_tsip)->word_2 = cpu_to_le32(NS_TSI_EMPTY))
-
-#define NS_TSQSIZE 8192
-#define NS_TSQ_NUM_ENTRIES 1024
-#define NS_TSQ_ALIGNMENT 8192
-
-#define NS_TSI_SCDISVBR NS_TSR_SCDISVBR
-
-#define ns_tsi_tmrof(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_1) == 0x00000000)
-#define ns_tsi_getscdindex(ns_tsip) \
-        ((le32_to_cpu((ns_tsip)->word_1) & 0xFFFF0000) >> 16)
-#define ns_tsi_getscqpos(ns_tsip) \
-        (le32_to_cpu((ns_tsip)->word_1) & 0x00007FFF)
-
-/* NICStAR structures located in local SRAM */
-
-/*
- * RCT - Receive Connection Table
- *
- * Written by both the NICStAR and the device driver.
- */
-
-typedef struct ns_rcte {
-	u32 word_1;
-	u32 buffer_handle;
-	u32 dma_address;
-	u32 aal5_crc32;
-} ns_rcte;
-
-#define NS_RCTE_BSFB            0x00200000	/* Rev. D only */
-#define NS_RCTE_NZGFC           0x00100000
-#define NS_RCTE_CONNECTOPEN     0x00080000
-#define NS_RCTE_AALMASK         0x00070000
-#define NS_RCTE_AAL0            0x00000000
-#define NS_RCTE_AAL34           0x00010000
-#define NS_RCTE_AAL5            0x00020000
-#define NS_RCTE_RCQ             0x00030000
-#define NS_RCTE_RAWCELLINTEN    0x00008000
-#define NS_RCTE_RXCONSTCELLADDR 0x00004000
-#define NS_RCTE_BUFFVALID       0x00002000
-#define NS_RCTE_FBDSIZE         0x00001000
-#define NS_RCTE_EFCI            0x00000800
-#define NS_RCTE_CLP             0x00000400
-#define NS_RCTE_CRCERROR        0x00000200
-#define NS_RCTE_CELLCOUNT_MASK  0x000001FF
-
-#define NS_RCTE_FBDSIZE_SM 0x00000000
-#define NS_RCTE_FBDSIZE_LG 0x00001000
-
-#define NS_RCT_ENTRY_SIZE 4	/* Number of dwords */
-
-   /* NOTE: We could make macros to contruct the first word of the RCTE,
-      but that doesn't seem to make much sense... */
-
-/*
- * FBD - Free Buffer Descriptor
- *
- * Written by the device driver using via the command register.
- */
-
-typedef struct ns_fbd {
-	u32 buffer_handle;
-	u32 dma_address;
-} ns_fbd;
-
-/*
- * TST - Transmit Schedule Table
- *
- * Written by the device driver.
- */
-
-typedef u32 ns_tste;
-
-#define NS_TST_OPCODE_MASK 0x60000000
-
-#define NS_TST_OPCODE_NULL     0x00000000	/* Insert null cell */
-#define NS_TST_OPCODE_FIXED    0x20000000	/* Cell from a fixed rate channel */
-#define NS_TST_OPCODE_VARIABLE 0x40000000
-#define NS_TST_OPCODE_END      0x60000000	/* Jump */
-
-#define ns_tste_make(opcode, sramad) (opcode | sramad)
-
-   /* NOTE:
-
-      - When the opcode is FIXED, sramad specifies the SRAM address of the
-      SCD for that fixed rate channel.
-      - When the opcode is END, sramad specifies the SRAM address of the
-      location of the next TST entry to read.
-    */
-
-/*
- * SCD - Segmentation Channel Descriptor
- *
- * Written by both the device driver and the NICStAR
- */
-
-typedef struct ns_scd {
-	u32 word_1;
-	u32 word_2;
-	u32 partial_aal5_crc;
-	u32 reserved;
-	ns_scqe cache_a;
-	ns_scqe cache_b;
-} ns_scd;
-
-#define NS_SCD_BASE_MASK_VAR 0xFFFFE000	/* Variable rate */
-#define NS_SCD_BASE_MASK_FIX 0xFFFFFC00	/* Fixed rate */
-#define NS_SCD_TAIL_MASK_VAR 0x00001FF0
-#define NS_SCD_TAIL_MASK_FIX 0x000003F0
-#define NS_SCD_HEAD_MASK_VAR 0x00001FF0
-#define NS_SCD_HEAD_MASK_FIX 0x000003F0
-#define NS_SCD_XMITFOREVER   0x02000000
-
-   /* NOTE: There are other fields in word 2 of the SCD, but as they should
-      not be needed in the device driver they are not defined here. */
-
-/* NICStAR local SRAM memory map */
-
-#define NS_RCT           0x00000
-#define NS_RCT_32_END    0x03FFF
-#define NS_RCT_128_END   0x0FFFF
-#define NS_UNUSED_32     0x04000
-#define NS_UNUSED_128    0x10000
-#define NS_UNUSED_END    0x1BFFF
-#define NS_TST_FRSCD     0x1C000
-#define NS_TST_FRSCD_END 0x1E7DB
-#define NS_VRSCD2        0x1E7DC
-#define NS_VRSCD2_END    0x1E7E7
-#define NS_VRSCD1        0x1E7E8
-#define NS_VRSCD1_END    0x1E7F3
-#define NS_VRSCD0        0x1E7F4
-#define NS_VRSCD0_END    0x1E7FF
-#define NS_RXFIFO        0x1E800
-#define NS_RXFIFO_END    0x1F7FF
-#define NS_SMFBQ         0x1F800
-#define NS_SMFBQ_END     0x1FBFF
-#define NS_LGFBQ         0x1FC00
-#define NS_LGFBQ_END     0x1FFFF
-
-/* NISCtAR operation registers */
-
-/* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */
-
-enum ns_regs {
-	DR0 = 0x00,		/* Data Register 0 R/W */
-	DR1 = 0x04,		/* Data Register 1 W */
-	DR2 = 0x08,		/* Data Register 2 W */
-	DR3 = 0x0C,		/* Data Register 3 W */
-	CMD = 0x10,		/* Command W */
-	CFG = 0x14,		/* Configuration R/W */
-	STAT = 0x18,		/* Status R/W */
-	RSQB = 0x1C,		/* Receive Status Queue Base W */
-	RSQT = 0x20,		/* Receive Status Queue Tail R */
-	RSQH = 0x24,		/* Receive Status Queue Head W */
-	CDC = 0x28,		/* Cell Drop Counter R/clear */
-	VPEC = 0x2C,		/* VPI/VCI Lookup Error Count R/clear */
-	ICC = 0x30,		/* Invalid Cell Count R/clear */
-	RAWCT = 0x34,		/* Raw Cell Tail R */
-	TMR = 0x38,		/* Timer R */
-	TSTB = 0x3C,		/* Transmit Schedule Table Base R/W */
-	TSQB = 0x40,		/* Transmit Status Queue Base W */
-	TSQT = 0x44,		/* Transmit Status Queue Tail R */
-	TSQH = 0x48,		/* Transmit Status Queue Head W */
-	GP = 0x4C,		/* General Purpose R/W */
-	VPM = 0x50		/* VPI/VCI Mask W */
-};
-
-/* NICStAR commands issued to the CMD register */
-
-/* Top 4 bits are command opcode, lower 28 are parameters. */
-
-#define NS_CMD_NO_OPERATION         0x00000000
-	/* params always 0 */
-
-#define NS_CMD_OPENCLOSE_CONNECTION 0x20000000
-	/* b19{1=open,0=close} b18-2{SRAM addr} */
-
-#define NS_CMD_WRITE_SRAM           0x40000000
-	/* b18-2{SRAM addr} b1-0{burst size} */
-
-#define NS_CMD_READ_SRAM            0x50000000
-	/* b18-2{SRAM addr} */
-
-#define NS_CMD_WRITE_FREEBUFQ       0x60000000
-	/* b0{large buf indicator} */
-
-#define NS_CMD_READ_UTILITY         0x80000000
-	/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
-
-#define NS_CMD_WRITE_UTILITY        0x90000000
-	/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
-
-#define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000)
-#define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION
-
-/* NICStAR configuration bits */
-
-#define NS_CFG_SWRST          0x80000000	/* Software Reset */
-#define NS_CFG_RXPATH         0x20000000	/* Receive Path Enable */
-#define NS_CFG_SMBUFSIZE_MASK 0x18000000	/* Small Receive Buffer Size */
-#define NS_CFG_LGBUFSIZE_MASK 0x06000000	/* Large Receive Buffer Size */
-#define NS_CFG_EFBIE          0x01000000	/* Empty Free Buffer Queue
-						   Interrupt Enable */
-#define NS_CFG_RSQSIZE_MASK   0x00C00000	/* Receive Status Queue Size */
-#define NS_CFG_ICACCEPT       0x00200000	/* Invalid Cell Accept */
-#define NS_CFG_IGNOREGFC      0x00100000	/* Ignore General Flow Control */
-#define NS_CFG_VPIBITS_MASK   0x000C0000	/* VPI/VCI Bits Size Select */
-#define NS_CFG_RCTSIZE_MASK   0x00030000	/* Receive Connection Table Size */
-#define NS_CFG_VCERRACCEPT    0x00008000	/* VPI/VCI Error Cell Accept */
-#define NS_CFG_RXINT_MASK     0x00007000	/* End of Receive PDU Interrupt
-						   Handling */
-#define NS_CFG_RAWIE          0x00000800	/* Raw Cell Qu' Interrupt Enable */
-#define NS_CFG_RSQAFIE        0x00000400	/* Receive Queue Almost Full
-						   Interrupt Enable */
-#define NS_CFG_RXRM           0x00000200	/* Receive RM Cells */
-#define NS_CFG_TMRROIE        0x00000080	/* Timer Roll Over Interrupt
-						   Enable */
-#define NS_CFG_TXEN           0x00000020	/* Transmit Operation Enable */
-#define NS_CFG_TXIE           0x00000010	/* Transmit Status Interrupt
-						   Enable */
-#define NS_CFG_TXURIE         0x00000008	/* Transmit Under-run Interrupt
-						   Enable */
-#define NS_CFG_UMODE          0x00000004	/* Utopia Mode (cell/byte) Select */
-#define NS_CFG_TSQFIE         0x00000002	/* Transmit Status Queue Full
-						   Interrupt Enable */
-#define NS_CFG_PHYIE          0x00000001	/* PHY Interrupt Enable */
-
-#define NS_CFG_SMBUFSIZE_48    0x00000000
-#define NS_CFG_SMBUFSIZE_96    0x08000000
-#define NS_CFG_SMBUFSIZE_240   0x10000000
-#define NS_CFG_SMBUFSIZE_2048  0x18000000
-
-#define NS_CFG_LGBUFSIZE_2048  0x00000000
-#define NS_CFG_LGBUFSIZE_4096  0x02000000
-#define NS_CFG_LGBUFSIZE_8192  0x04000000
-#define NS_CFG_LGBUFSIZE_16384 0x06000000
-
-#define NS_CFG_RSQSIZE_2048 0x00000000
-#define NS_CFG_RSQSIZE_4096 0x00400000
-#define NS_CFG_RSQSIZE_8192 0x00800000
-
-#define NS_CFG_VPIBITS_0 0x00000000
-#define NS_CFG_VPIBITS_1 0x00040000
-#define NS_CFG_VPIBITS_2 0x00080000
-#define NS_CFG_VPIBITS_8 0x000C0000
-
-#define NS_CFG_RCTSIZE_4096_ENTRIES  0x00000000
-#define NS_CFG_RCTSIZE_8192_ENTRIES  0x00010000
-#define NS_CFG_RCTSIZE_16384_ENTRIES 0x00020000
-
-#define NS_CFG_RXINT_NOINT   0x00000000
-#define NS_CFG_RXINT_NODELAY 0x00001000
-#define NS_CFG_RXINT_314US   0x00002000
-#define NS_CFG_RXINT_624US   0x00003000
-#define NS_CFG_RXINT_899US   0x00004000
-
-/* NICStAR STATus bits */
-
-#define NS_STAT_SFBQC_MASK 0xFF000000	/* hi 8 bits Small Buffer Queue Count */
-#define NS_STAT_LFBQC_MASK 0x00FF0000	/* hi 8 bits Large Buffer Queue Count */
-#define NS_STAT_TSIF       0x00008000	/* Transmit Status Queue Indicator */
-#define NS_STAT_TXICP      0x00004000	/* Transmit Incomplete PDU */
-#define NS_STAT_TSQF       0x00001000	/* Transmit Status Queue Full */
-#define NS_STAT_TMROF      0x00000800	/* Timer Overflow */
-#define NS_STAT_PHYI       0x00000400	/* PHY Device Interrupt */
-#define NS_STAT_CMDBZ      0x00000200	/* Command Busy */
-#define NS_STAT_SFBQF      0x00000100	/* Small Buffer Queue Full */
-#define NS_STAT_LFBQF      0x00000080	/* Large Buffer Queue Full */
-#define NS_STAT_RSQF       0x00000040	/* Receive Status Queue Full */
-#define NS_STAT_EOPDU      0x00000020	/* End of PDU */
-#define NS_STAT_RAWCF      0x00000010	/* Raw Cell Flag */
-#define NS_STAT_SFBQE      0x00000008	/* Small Buffer Queue Empty */
-#define NS_STAT_LFBQE      0x00000004	/* Large Buffer Queue Empty */
-#define NS_STAT_RSQAF      0x00000002	/* Receive Status Queue Almost Full */
-
-#define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23)
-#define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15)
-
-/* #defines which depend on other #defines */
-
-#define NS_TST0 NS_TST_FRSCD
-#define NS_TST1 (NS_TST_FRSCD + NS_TST_NUM_ENTRIES + 1)
-
-#define NS_FRSCD (NS_TST1 + NS_TST_NUM_ENTRIES + 1)
-#define NS_FRSCD_SIZE 12	/* 12 dwords */
-#define NS_FRSCD_NUM ((NS_TST_FRSCD_END + 1 - NS_FRSCD) / NS_FRSCD_SIZE)
-
-#if (NS_SMBUFSIZE == 48)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_48
-#elif (NS_SMBUFSIZE == 96)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_96
-#elif (NS_SMBUFSIZE == 240)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_240
-#elif (NS_SMBUFSIZE == 2048)
-#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_2048
-#else
-#error NS_SMBUFSIZE is incorrect in nicstar.h
-#endif /* NS_SMBUFSIZE */
-
-#if (NS_LGBUFSIZE == 2048)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_2048
-#elif (NS_LGBUFSIZE == 4096)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_4096
-#elif (NS_LGBUFSIZE == 8192)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_8192
-#elif (NS_LGBUFSIZE == 16384)
-#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_16384
-#else
-#error NS_LGBUFSIZE is incorrect in nicstar.h
-#endif /* NS_LGBUFSIZE */
-
-#if (NS_RSQSIZE == 2048)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_2048
-#elif (NS_RSQSIZE == 4096)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_4096
-#elif (NS_RSQSIZE == 8192)
-#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_8192
-#else
-#error NS_RSQSIZE is incorrect in nicstar.h
-#endif /* NS_RSQSIZE */
-
-#if (NS_VPIBITS == 0)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_0
-#elif (NS_VPIBITS == 1)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_1
-#elif (NS_VPIBITS == 2)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_2
-#elif (NS_VPIBITS == 8)
-#define NS_CFG_VPIBITS NS_CFG_VPIBITS_8
-#else
-#error NS_VPIBITS is incorrect in nicstar.h
-#endif /* NS_VPIBITS */
-
-#ifdef RCQ_SUPPORT
-#define NS_CFG_RAWIE_OPT NS_CFG_RAWIE
-#else
-#define NS_CFG_RAWIE_OPT 0x00000000
-#endif /* RCQ_SUPPORT */
-
-#ifdef ENABLE_TSQFIE
-#define NS_CFG_TSQFIE_OPT NS_CFG_TSQFIE
-#else
-#define NS_CFG_TSQFIE_OPT 0x00000000
-#endif /* ENABLE_TSQFIE */
-
-/* PCI stuff */
-
-#ifndef PCI_VENDOR_ID_IDT
-#define PCI_VENDOR_ID_IDT 0x111D
-#endif /* PCI_VENDOR_ID_IDT */
-
-#ifndef PCI_DEVICE_ID_IDT_IDT77201
-#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
-#endif /* PCI_DEVICE_ID_IDT_IDT77201 */
-
-/* Device driver structures */
-
-struct ns_skb_prv {
-	u32 buf_type;		/* BUF_SM/BUF_LG/BUF_NONE */
-	u32 dma;
-	int iovcnt;
-};
-
-#define NS_PRV_BUFTYPE(skb)   \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->buf_type)
-#define NS_PRV_DMA(skb) \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->dma)
-#define NS_PRV_IOVCNT(skb) \
-        (((struct ns_skb_prv *)(ATM_SKB(skb)+1))->iovcnt)
-
-typedef struct tsq_info {
-	void *org;
-        dma_addr_t dma;
-	ns_tsi *base;
-	ns_tsi *next;
-	ns_tsi *last;
-} tsq_info;
-
-typedef struct scq_info {
-	void *org;
-	dma_addr_t dma;
-	ns_scqe *base;
-	ns_scqe *last;
-	ns_scqe *next;
-	volatile ns_scqe *tail;	/* Not related to the nicstar register */
-	unsigned num_entries;
-	struct sk_buff **skb;	/* Pointer to an array of pointers
-				   to the sk_buffs used for tx */
-	u32 scd;		/* SRAM address of the corresponding
-				   SCD */
-	int tbd_count;		/* Only meaningful on variable rate */
-	wait_queue_head_t scqfull_waitq;
-	volatile char full;	/* SCQ full indicator */
-	spinlock_t lock;	/* SCQ spinlock */
-} scq_info;
-
-typedef struct rsq_info {
-	void *org;
-        dma_addr_t dma;
-	ns_rsqe *base;
-	ns_rsqe *next;
-	ns_rsqe *last;
-} rsq_info;
-
-typedef struct skb_pool {
-	volatile int count;	/* number of buffers in the queue */
-	struct sk_buff_head queue;
-} skb_pool;
-
-/* NOTE: for small and large buffer pools, the count is not used, as the
-         actual value used for buffer management is the one read from the
-	 card. */
-
-typedef struct vc_map {
-	volatile unsigned int tx:1;	/* TX vc? */
-	volatile unsigned int rx:1;	/* RX vc? */
-	struct atm_vcc *tx_vcc, *rx_vcc;
-	struct sk_buff *rx_iov;	/* RX iovector skb */
-	scq_info *scq;		/* To keep track of the SCQ */
-	u32 cbr_scd;		/* SRAM address of the corresponding
-				   SCD. 0x00000000 for UBR/VBR/ABR */
-	int tbd_count;
-} vc_map;
-
-typedef struct ns_dev {
-	int index;		/* Card ID to the device driver */
-	int sram_size;		/* In k x 32bit words. 32 or 128 */
-	void __iomem *membase;	/* Card's memory base address */
-	unsigned long max_pcr;
-	int rct_size;		/* Number of entries */
-	int vpibits;
-	int vcibits;
-	struct pci_dev *pcidev;
-	struct idr idr;
-	struct atm_dev *atmdev;
-	tsq_info tsq;
-	rsq_info rsq;
-	scq_info *scq0, *scq1, *scq2;	/* VBR SCQs */
-	skb_pool sbpool;	/* Small buffers */
-	skb_pool lbpool;	/* Large buffers */
-	skb_pool hbpool;	/* Pre-allocated huge buffers */
-	skb_pool iovpool;	/* iovector buffers */
-	volatile int efbie;	/* Empty free buf. queue int. enabled */
-	volatile u32 tst_addr;	/* SRAM address of the TST in use */
-	volatile int tst_free_entries;
-	vc_map vcmap[NS_MAX_RCTSIZE];
-	vc_map *tste2vc[NS_TST_NUM_ENTRIES];
-	vc_map *scd2vc[NS_FRSCD_NUM];
-	buf_nr sbnr;
-	buf_nr lbnr;
-	buf_nr hbnr;
-	buf_nr iovnr;
-	int sbfqc;
-	int lbfqc;
-	struct sk_buff *sm_handle;
-	u32 sm_addr;
-	struct sk_buff *lg_handle;
-	u32 lg_addr;
-	struct sk_buff *rcbuf;	/* Current raw cell buffer */
-        struct ns_rcqe *rawcell;
-	u32 rawch;		/* Raw cell queue head */
-	unsigned intcnt;	/* Interrupt counter */
-	spinlock_t int_lock;	/* Interrupt lock */
-	spinlock_t res_lock;	/* Card resource lock */
-} ns_dev;
-
-   /* NOTE: Each tste2vc entry relates a given TST entry to the corresponding
-      CBR vc. If the entry is not allocated, it must be NULL.
-
-      There are two TSTs so the driver can modify them on the fly
-      without stopping the transmission.
-
-      scd2vc allows us to find out unused fixed rate SCDs, because
-      they must have a NULL pointer here. */
-
-#endif /* _LINUX_NICSTAR_H_ */
diff --git a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c
deleted file mode 100644
index 791f69a..0000000
--- a/drivers/atm/nicstarmac.c
+++ /dev/null
@@ -1,244 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * this file included by nicstar.c
- */
-
-/*
- * nicstarmac.c
- * Read this ForeRunner's MAC address from eprom/eeprom
- */
-
-#include <linux/kernel.h>
-
-typedef void __iomem *virt_addr_t;
-
-#define CYCLE_DELAY 5
-
-#define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
-                                  udelay((useconds));}
-/*
- * The following tables represent the timing diagrams found in
- * the Data Sheet for the Xicor X25020 EEProm.  The #defines below
- * represent the bits in the NICStAR's General Purpose register
- * that must be toggled for the corresponding actions on the EEProm
- * to occur.
- */
-
-/* Write Data To EEProm from SI line on rising edge of CLK */
-/* Read Data From EEProm on falling edge of CLK */
-
-#define CS_HIGH		0x0002	/* Chip select high */
-#define CS_LOW		0x0000	/* Chip select low (active low) */
-#define CLK_HIGH	0x0004	/* Clock high */
-#define CLK_LOW		0x0000	/* Clock low  */
-#define SI_HIGH		0x0001	/* Serial input data high */
-#define SI_LOW		0x0000	/* Serial input data low */
-
-/* Read Status Register = 0000 0101b */
-#if 0
-static u_int32_t rdsrtab[] = {
-	CS_HIGH | CLK_HIGH,
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,	/* 1 */
-	CLK_LOW | SI_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH	/* 1 */
-};
-#endif /*  0  */
-
-/* Read from EEPROM = 0000 0011b */
-static u_int32_t readtab[] = {
-	/*
-	   CS_HIGH | CLK_HIGH,
-	 */
-	CS_LOW | CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW,
-	CLK_HIGH,		/* 0 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH,	/* 1 */
-	CLK_LOW | SI_HIGH,
-	CLK_HIGH | SI_HIGH	/* 1 */
-};
-
-/* Clock to read from/write to the eeprom */
-static u_int32_t clocktab[] = {
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW,
-	CLK_HIGH,
-	CLK_LOW
-};
-
-#define NICSTAR_REG_WRITE(bs, reg, val) \
-	while ( readl(bs + STAT) & 0x0200 ) ; \
-	writel((val),(base)+(reg))
-#define NICSTAR_REG_READ(bs, reg) \
-	readl((base)+(reg))
-#define NICSTAR_REG_GENERAL_PURPOSE GP
-
-/*
- * This routine will clock the Read_Status_reg function into the X2520
- * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
- * register.  
- */
-#if 0
-u_int32_t nicstar_read_eprom_status(virt_addr_t base)
-{
-	u_int32_t val;
-	u_int32_t rbyte;
-	int32_t i, j;
-
-	/* Send read instruction */
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | rdsrtab[i]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	/* Done sending instruction - now pull data off of bit 16, MSB first */
-	/* Data clocked out of eeprom on falling edge of clock */
-
-	rbyte = 0;
-	for (i = 7, j = 0; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
-			    & 0x00010000) >> 16) << i);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
-	osp_MicroDelay(CYCLE_DELAY);
-	return rbyte;
-}
-#endif /*  0  */
-
-/*
- * This routine will clock the Read_data function into the X2520
- * eeprom, followed by the address to read from, through the NicSTaR's General
- * Purpose register.  
- */
-
-static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
-{
-	u_int32_t val = 0;
-	int i, j = 0;
-	u_int8_t tempread = 0;
-
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	/* Send READ instruction */
-	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | readtab[i]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	/* Next, we need to send the byte address to read from */
-	for (i = 7; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++] | ((offset >> i) & 1)));
-		osp_MicroDelay(CYCLE_DELAY);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++] | ((offset >> i) & 1)));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	j = 0;
-
-	/* Now, we can read data from the eeprom by clocking it in */
-	for (i = 7; i >= 0; i--) {
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-		tempread |=
-		    (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
-		       & 0x00010000) >> 16) << i);
-		NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-				  (val | clocktab[j++]));
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
-	osp_MicroDelay(CYCLE_DELAY);
-	return tempread;
-}
-
-static void nicstar_init_eprom(virt_addr_t base)
-{
-	u_int32_t val;
-
-	/*
-	 * turn chip select off
-	 */
-	val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_HIGH));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_LOW));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_HIGH));
-	osp_MicroDelay(CYCLE_DELAY);
-
-	NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
-			  (val | CS_HIGH | CLK_LOW));
-	osp_MicroDelay(CYCLE_DELAY);
-}
-
-/*
- * This routine will be the interface to the ReadPromByte function
- * above.
- */
-
-static void
-nicstar_read_eprom(virt_addr_t base,
-		   u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
-{
-	u_int i;
-
-	for (i = 0; i < nbytes; i++) {
-		buffer[i] = read_eprom_byte(base, prom_offset);
-		++prom_offset;
-		osp_MicroDelay(CYCLE_DELAY);
-	}
-}
diff --git a/drivers/atm/nicstarmac.copyright b/drivers/atm/nicstarmac.copyright
deleted file mode 100644
index 180531a..0000000
--- a/drivers/atm/nicstarmac.copyright
+++ /dev/null
@@ -1,61 +0,0 @@
-/* nicstar.c  v0.22  Jawaid Bazyar (bazyar@hypermall.com)
- * nicstar.c, M. Welsh (matt.welsh@cl.cam.ac.uk)
- *
- * Hacked October, 1997 by Jawaid Bazyar, Interlink Advertising Services Inc.
- * 	http://www.hypermall.com/
- * 10/1/97 - commented out CFG_PHYIE bit - we don't care when the PHY
- *	interrupts us (except possibly for removal/insertion of the cable?)
- * 10/4/97 - began heavy inline documentation of the code. Corrected typos
- *	and spelling mistakes.
- * 10/5/97 - added code to handle PHY interrupts, disable PHY on
- *	loss of link, and correctly re-enable PHY when link is
- *	re-established. (put back CFG_PHYIE)
- *
- *   Modified to work with the IDT7721 nicstar -- AAL5 (tested) only.
- *
- * R. D. Rechenmacher <ron@fnal.gov>, Aug. 6, 1997
- *
- * Linux driver for the IDT77201 NICStAR PCI ATM controller.
- * PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155;
- * see init_nicstar() for PHY initialization to change this. This driver
- * expects the Linux ATM stack to support scatter-gather lists 
- * (skb->atm.iovcnt != 0) for Rx skb's passed to vcc->push.
- *
- * Implementing minimal-copy of received data:
- *   IDT always receives data into a small buffer, then large buffers
- *     as needed. This means that data must always be copied to create
- *     the linear buffer needed by most non-ATM protocol stacks (e.g. IP)
- *     Fix is simple: make large buffers large enough to hold entire
- *     SDU, and leave <small_buffer_data> bytes empty at the start. Then
- *     copy small buffer contents to head of large buffer.
- *   Trick is to avoid fragmenting Linux, due to need for a lot of large
- *     buffers. This is done by 2 things:
- *       1) skb->destructor / skb->atm.recycle_buffer
- *            combined, allow nicstar_free_rx_skb to be called to
- *            recycle large data buffers
- *       2) skb_clone of received buffers
- *   See nicstar_free_rx_skb and linearize_buffer for implementation
- *     details.
- *
- *
- *
- * Copyright (c) 1996 University of Cambridge Computer Laboratory
- *
- *   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, write to the Free Software
- *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * M. Welsh, 6 July 1996
- *
- *
- */
diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c
deleted file mode 100644
index bb588c9..0000000
--- a/drivers/atm/suni.c
+++ /dev/null
@@ -1,391 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * drivers/atm/suni.c - S/UNI PHY driver
- *
- * Supports the following:
- * 	PMC PM5346 S/UNI LITE
- * 	PMC PM5350 S/UNI 155 ULTRA
- * 	PMC PM5355 S/UNI 622
- */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#include <linux/module.h>
-#include <linux/jiffies.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/atmdev.h>
-#include <linux/sonet.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/capability.h>
-#include <linux/slab.h>
-#include <asm/param.h>
-#include <linux/uaccess.h>
-#include <linux/atomic.h>
-
-#include "suni.h"
-
-
-#if 0
-#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
-#else
-#define DPRINTK(format,args...)
-#endif
-
-#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
-
-#define PUT(val,reg) dev->ops->phy_put(dev,val,SUNI_##reg)
-#define GET(reg) dev->ops->phy_get(dev,SUNI_##reg)
-#define REG_CHANGE(mask,shift,value,reg) \
-  PUT((GET(reg) & ~(mask)) | ((value) << (shift)),reg)
-
-
-static struct timer_list poll_timer;
-static struct suni_priv *sunis = NULL;
-static DEFINE_SPINLOCK(sunis_lock);
-
-
-#define ADD_LIMITED(s,v) \
-    atomic_add((v),&stats->s); \
-    if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
-
-
-static void suni_hz(struct timer_list *timer)
-{
-	struct suni_priv *walk;
-	struct atm_dev *dev;
-	struct k_sonet_stats *stats;
-
-	for (walk = sunis; walk; walk = walk->next) {
-		dev = walk->dev;
-		stats = &walk->sonet_stats;
-		PUT(0,MRI); /* latch counters */
-		udelay(1);
-		ADD_LIMITED(section_bip,(GET(RSOP_SBL) & 0xff) |
-		    ((GET(RSOP_SBM) & 0xff) << 8));
-		ADD_LIMITED(line_bip,(GET(RLOP_LBL) & 0xff) |
-		    ((GET(RLOP_LB) & 0xff) << 8) |
-		    ((GET(RLOP_LBM) & 0xf) << 16));
-		ADD_LIMITED(path_bip,(GET(RPOP_PBL) & 0xff) |
-		    ((GET(RPOP_PBM) & 0xff) << 8));
-		ADD_LIMITED(line_febe,(GET(RLOP_LFL) & 0xff) |
-		    ((GET(RLOP_LF) & 0xff) << 8) |
-		    ((GET(RLOP_LFM) & 0xf) << 16));
-		ADD_LIMITED(path_febe,(GET(RPOP_PFL) & 0xff) |
-		    ((GET(RPOP_PFM) & 0xff) << 8));
-		ADD_LIMITED(corr_hcs,GET(RACP_CHEC) & 0xff);
-		ADD_LIMITED(uncorr_hcs,GET(RACP_UHEC) & 0xff);
-		ADD_LIMITED(rx_cells,(GET(RACP_RCCL) & 0xff) |
-		    ((GET(RACP_RCC) & 0xff) << 8) |
-		    ((GET(RACP_RCCM) & 7) << 16));
-		ADD_LIMITED(tx_cells,(GET(TACP_TCCL) & 0xff) |
-		    ((GET(TACP_TCC) & 0xff) << 8) |
-		    ((GET(TACP_TCCM) & 7) << 16));
-	}
-	if (timer) mod_timer(&poll_timer,jiffies+HZ);
-}
-
-
-#undef ADD_LIMITED
-
-
-static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
-{
-	struct sonet_stats tmp;
-	int error = 0;
-
-	sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
-	if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
-	if (zero && !error) sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp);
-	return error ? -EFAULT : 0;
-}
-
-
-#define HANDLE_FLAG(flag,reg,bit) \
-  if (todo & flag) { \
-    if (set) PUT(GET(reg) | bit,reg); \
-    else PUT(GET(reg) & ~bit,reg); \
-    todo &= ~flag; \
-  }
-
-
-static int change_diag(struct atm_dev *dev,void __user *arg,int set)
-{
-	int todo;
-
-	if (get_user(todo,(int __user *)arg)) return -EFAULT;
-	HANDLE_FLAG(SONET_INS_SBIP,TSOP_DIAG,SUNI_TSOP_DIAG_DBIP8);
-	HANDLE_FLAG(SONET_INS_LBIP,TLOP_DIAG,SUNI_TLOP_DIAG_DBIP);
-	HANDLE_FLAG(SONET_INS_PBIP,TPOP_CD,SUNI_TPOP_DIAG_DB3);
-	HANDLE_FLAG(SONET_INS_FRAME,RSOP_CIE,SUNI_RSOP_CIE_FOOF);
-	HANDLE_FLAG(SONET_INS_LAIS,TSOP_CTRL,SUNI_TSOP_CTRL_LAIS);
-	HANDLE_FLAG(SONET_INS_PAIS,TPOP_CD,SUNI_TPOP_DIAG_PAIS);
-	HANDLE_FLAG(SONET_INS_LOS,TSOP_DIAG,SUNI_TSOP_DIAG_DLOS);
-	HANDLE_FLAG(SONET_INS_HCS,TACP_CS,SUNI_TACP_CS_DHCS);
-	return put_user(todo,(int __user *)arg) ? -EFAULT : 0;
-}
-
-
-#undef HANDLE_FLAG
-
-
-static int get_diag(struct atm_dev *dev,void __user *arg)
-{
-	int set;
-
-	set = 0;
-	if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DBIP8) set |= SONET_INS_SBIP;
-	if (GET(TLOP_DIAG) & SUNI_TLOP_DIAG_DBIP) set |= SONET_INS_LBIP;
-	if (GET(TPOP_CD) & SUNI_TPOP_DIAG_DB3) set |= SONET_INS_PBIP;
-	/* SONET_INS_FRAME is one-shot only */
-	if (GET(TSOP_CTRL) & SUNI_TSOP_CTRL_LAIS) set |= SONET_INS_LAIS;
-	if (GET(TPOP_CD) & SUNI_TPOP_DIAG_PAIS) set |= SONET_INS_PAIS;
-	if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DLOS) set |= SONET_INS_LOS;
-	if (GET(TACP_CS) & SUNI_TACP_CS_DHCS) set |= SONET_INS_HCS;
-	return put_user(set,(int __user *)arg) ? -EFAULT : 0;
-}
-
-
-static int set_loopback(struct atm_dev *dev,int mode)
-{
-	unsigned char control;
-	int reg, dle, lle;
-
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		reg = SUNI_MCM;
-		dle = SUNI_MCM_DLE;
-		lle = SUNI_MCM_LLE;
-	} else {
-		reg = SUNI_MCT;
-		dle = SUNI_MCT_DLE;
-		lle = SUNI_MCT_LLE;
-	}
-
-	control = dev->ops->phy_get(dev, reg) & ~(dle | lle);
-	switch (mode) {
-		case ATM_LM_NONE:
-			break;
-		case ATM_LM_LOC_PHY:
-			control |= dle;
-			break;
-		case ATM_LM_RMT_PHY:
-			control |= lle;
-			break;
-		default:
-			return -EINVAL;
-	}
-	dev->ops->phy_put(dev, control, reg);
-	PRIV(dev)->loop_mode = mode;
-	return 0;
-}
-
-/*
- * SONET vs. SDH Configuration
- *
- * Z0INS (register 0x06): 0 for SONET, 1 for SDH
- * ENSS (register 0x3D): 0 for SONET, 1 for SDH
- * LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
- * LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
- * S[1:0] (register 0x46): 00 for SONET, 10 for SDH
- */
-
-static int set_sonet(struct atm_dev *dev)
-{
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC);
-		PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
-		PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
-	}
-
-	REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
-		   SUNI_TPOP_S_SONET, TPOP_APM);
-
-	return 0;
-}
-
-static int set_sdh(struct atm_dev *dev)
-{
-	if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
-		PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC);
-		PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
-		PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
-	}
-
-	REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
-		   SUNI_TPOP_S_SDH, TPOP_APM);
-
-	return 0;
-}
-
-
-static int get_framing(struct atm_dev *dev, void __user *arg)
-{
-	int framing;
-	unsigned char s;
-
-
-	s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT;
-	if (s == SUNI_TPOP_S_SONET)
-		framing = SONET_FRAME_SONET;
-	else
-		framing = SONET_FRAME_SDH;
-
-	return put_user(framing, (int __user *) arg) ? -EFAULT : 0;
-}
-
-static int set_framing(struct atm_dev *dev, void __user *arg)
-{
-	int mode;
-
-	if (get_user(mode, (int __user *) arg))
-		return -EFAULT;
-
-	if (mode == SONET_FRAME_SONET)
-		return set_sonet(dev);
-	else if (mode == SONET_FRAME_SDH)
-		return set_sdh(dev);
-
-	return -EINVAL;
-}
-
-
-static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
-{
-	switch (cmd) {
-		case SONET_GETSTATZ:
-		case SONET_GETSTAT:
-			return fetch_stats(dev, arg, cmd == SONET_GETSTATZ);
-		case SONET_SETDIAG:
-			return change_diag(dev,arg,1);
-		case SONET_CLRDIAG:
-			return change_diag(dev,arg,0);
-		case SONET_GETDIAG:
-			return get_diag(dev,arg);
-		case SONET_SETFRAMING:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			return set_framing(dev, arg);
-		case SONET_GETFRAMING:
-			return get_framing(dev, arg);
-		case SONET_GETFRSENSE:
-			return -EINVAL;
-		case ATM_SETLOOP:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			return set_loopback(dev,(int)(unsigned long)arg);
-		case ATM_GETLOOP:
-			return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-			    -EFAULT : 0;
-		case ATM_QUERYLOOP:
-			return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY,
-			    (int __user *) arg) ? -EFAULT : 0;
-		default:
-			return -ENOIOCTLCMD;
-	}
-}
-
-
-static void poll_los(struct atm_dev *dev)
-{
-	atm_dev_signal_change(dev,
-		GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ?
-		ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND);
-}
-
-
-static void suni_int(struct atm_dev *dev)
-{
-	poll_los(dev);
-	printk(KERN_NOTICE "%s(itf %d): signal %s\n",dev->type,dev->number,
-	    dev->signal == ATM_PHY_SIG_LOST ?  "lost" : "detected again");
-}
-
-
-static int suni_start(struct atm_dev *dev)
-{
-	unsigned long flags;
-	int first;
-
-	spin_lock_irqsave(&sunis_lock,flags);
-	first = !sunis;
-	PRIV(dev)->next = sunis;
-	sunis = PRIV(dev);
-	spin_unlock_irqrestore(&sunis_lock,flags);
-	memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
-	PUT(GET(RSOP_CIE) | SUNI_RSOP_CIE_LOSE,RSOP_CIE);
-		/* interrupt on loss of signal */
-	poll_los(dev); /* ... and clear SUNI interrupts */
-	if (dev->signal == ATM_PHY_SIG_LOST)
-		printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
-		    dev->number);
-	PRIV(dev)->loop_mode = ATM_LM_NONE;
-	suni_hz(NULL); /* clear SUNI counters */
-	(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
-	if (first) {
-		timer_setup(&poll_timer, suni_hz, 0);
-		poll_timer.expires = jiffies+HZ;
-#if 0
-printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.list.prev,
-    (unsigned long) poll_timer.list.next);
-#endif
-		add_timer(&poll_timer);
-	}
-	return 0;
-}
-
-
-static int suni_stop(struct atm_dev *dev)
-{
-	struct suni_priv **walk;
-	unsigned long flags;
-
-	/* let SAR driver worry about stopping interrupts */
-	spin_lock_irqsave(&sunis_lock,flags);
-	for (walk = &sunis; *walk != PRIV(dev);
-	    walk = &PRIV((*walk)->dev)->next);
-	*walk = PRIV((*walk)->dev)->next;
-	if (!sunis) timer_delete_sync(&poll_timer);
-	spin_unlock_irqrestore(&sunis_lock,flags);
-	kfree(PRIV(dev));
-
-	return 0;
-}
-
-
-static const struct atmphy_ops suni_ops = {
-	.start		= suni_start,
-	.ioctl		= suni_ioctl,
-	.interrupt	= suni_int,
-	.stop		= suni_stop,
-};
-
-
-int suni_init(struct atm_dev *dev)
-{
-	unsigned char mri;
-
-	if (!(dev->phy_data = kmalloc_obj(struct suni_priv)))
-		return -ENOMEM;
-	PRIV(dev)->dev = dev;
-
-	mri = GET(MRI); /* reset SUNI */
-	PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT;
-	PUT(mri | SUNI_MRI_RESET,MRI);
-	PUT(mri,MRI);
-	PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */
-        set_sonet(dev);
-	REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP,
-	    TACP_IUCHP); /* idle cells */
-	PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP);
-	dev->phy = &suni_ops;
-
-	return 0;
-}
-
-EXPORT_SYMBOL(suni_init);
-
-MODULE_DESCRIPTION("S/UNI PHY driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/atm/suni.h b/drivers/atm/suni.h
deleted file mode 100644
index d28a50d..0000000
--- a/drivers/atm/suni.h
+++ /dev/null
@@ -1,242 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * drivers/atm/suni.h - S/UNI PHY driver
- */
- 
-/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
-
-#ifndef DRIVER_ATM_SUNI_H
-#define DRIVER_ATM_SUNI_H
-
-#include <linux/atmdev.h>
-#include <linux/atmioc.h>
-#include <linux/sonet.h>
-
-/* SUNI registers */
-
-#define SUNI_MRI		0x00	/* Master Reset and Identity / Load
-					   Meter */
-#define SUNI_MC			0x01	/* Master Configuration */
-#define SUNI_MIS		0x02	/* Master Interrupt Status */
-			  /* no 0x03 */
-#define SUNI_MCM		0x04	/* Master Clock Monitor */
-#define SUNI_MCT		0x05	/* Master Control */
-#define SUNI_CSCS		0x06	/* Clock Synthesis Control and Status */
-#define SUNI_CRCS		0x07	/* Clock Recovery Control and Status */
-			     /* 0x08-0x0F reserved */
-#define SUNI_RSOP_CIE		0x10	/* RSOP Control/Interrupt Enable */
-#define SUNI_RSOP_SIS		0x11	/* RSOP Status/Interrupt Status */
-#define SUNI_RSOP_SBL		0x12	/* RSOP Section BIP-8 LSB */
-#define SUNI_RSOP_SBM		0x13	/* RSOP Section BIP-8 MSB */
-#define SUNI_TSOP_CTRL		0x14	/* TSOP Control */
-#define SUNI_TSOP_DIAG		0x15	/* TSOP Diagnostic */
-			     /* 0x16-0x17 reserved */
-#define SUNI_RLOP_CS		0x18	/* RLOP Control/Status */
-#define SUNI_RLOP_IES		0x19	/* RLOP Interrupt Enable/Status */
-#define SUNI_RLOP_LBL		0x1A	/* RLOP Line BIP-8/24 LSB */
-#define SUNI_RLOP_LB		0x1B	/* RLOP Line BIP-8/24 */
-#define SUNI_RLOP_LBM		0x1C	/* RLOP Line BIP-8/24 MSB */
-#define SUNI_RLOP_LFL		0x1D	/* RLOP Line FEBE LSB */
-#define SUNI_RLOP_LF 		0x1E	/* RLOP Line FEBE */
-#define SUNI_RLOP_LFM		0x1F	/* RLOP Line FEBE MSB */
-#define SUNI_TLOP_CTRL		0x20	/* TLOP Control */
-#define SUNI_TLOP_DIAG		0x21	/* TLOP Diagnostic */
-			     /* 0x22-0x27 reserved */
-#define SUNI_SSTB_CTRL		0x28
-#define SUNI_RPOP_SC		0x30	/* RPOP Status/Control */
-#define SUNI_RPOP_IS		0x31	/* RPOP Interrupt Status */
-			     /* 0x32 reserved */
-#define SUNI_RPOP_IE		0x33	/* RPOP Interrupt Enable */
-			     /* 0x34-0x36 reserved */
-#define SUNI_RPOP_PSL		0x37	/* RPOP Path Signal Label */
-#define SUNI_RPOP_PBL		0x38	/* RPOP Path BIP-8 LSB */
-#define SUNI_RPOP_PBM		0x39	/* RPOP Path BIP-8 MSB */
-#define SUNI_RPOP_PFL		0x3A	/* RPOP Path FEBE LSB */
-#define SUNI_RPOP_PFM		0x3B	/* RPOP Path FEBE MSB */
-			     /* 0x3C reserved */
-#define SUNI_RPOP_PBC		0x3D	/* RPOP Path BIP-8 Configuration */
-#define SUNI_RPOP_RC		0x3D	/* RPOP Ring Control (PM5355) */
-			     /* 0x3E-0x3F reserved */
-#define SUNI_TPOP_CD		0x40	/* TPOP Control/Diagnostic */
-#define SUNI_TPOP_PC		0x41	/* TPOP Pointer Control */
-			     /* 0x42-0x44 reserved */
-#define SUNI_TPOP_APL		0x45	/* TPOP Arbitrary Pointer LSB */
-#define SUNI_TPOP_APM		0x46	/* TPOP Arbitrary Pointer MSB */
-			     /* 0x47 reserved */
-#define SUNI_TPOP_PSL		0x48	/* TPOP Path Signal Label */
-#define SUNI_TPOP_PS		0x49	/* TPOP Path Status */
-			     /* 0x4A-0x4F reserved */
-#define SUNI_RACP_CS		0x50	/* RACP Control/Status */
-#define SUNI_RACP_IES		0x51	/* RACP Interrupt Enable/Status */
-#define SUNI_RACP_MHP		0x52	/* RACP Match Header Pattern */
-#define SUNI_RACP_MHM		0x53	/* RACP Match Header Mask */
-#define SUNI_RACP_CHEC		0x54	/* RACP Correctable HCS Error Count */
-#define SUNI_RACP_UHEC		0x55	/* RACP Uncorrectable HCS Err Count */
-#define SUNI_RACP_RCCL		0x56	/* RACP Receive Cell Counter LSB */
-#define SUNI_RACP_RCC		0x57	/* RACP Receive Cell Counter */
-#define SUNI_RACP_RCCM		0x58	/* RACP Receive Cell Counter MSB */
-#define SUNI_RACP_CFG		0x59	/* RACP Configuration */
-			     /* 0x5A-0x5F reserved */
-#define SUNI_TACP_CS		0x60	/* TACP Control/Status */
-#define SUNI_TACP_IUCHP		0x61	/* TACP Idle/Unassigned Cell Hdr Pat */
-#define SUNI_TACP_IUCPOP	0x62	/* TACP Idle/Unassigned Cell Payload
-					   Octet Pattern */
-#define SUNI_TACP_FIFO		0x63	/* TACP FIFO Configuration */
-#define SUNI_TACP_TCCL		0x64	/* TACP Transmit Cell Counter LSB */
-#define SUNI_TACP_TCC		0x65	/* TACP Transmit Cell Counter */
-#define SUNI_TACP_TCCM		0x66	/* TACP Transmit Cell Counter MSB */
-#define SUNI_TACP_CFG		0x67	/* TACP Configuration */
-#define SUNI_SPTB_CTRL		0x68	/* SPTB Control */
-			     /* 0x69-0x7F reserved */
-#define	SUNI_MT			0x80	/* Master Test */
-			     /* 0x81-0xFF reserved */
-
-/* SUNI register values */
-
-
-/* MRI is reg 0 */
-#define SUNI_MRI_ID		0x0f	/* R, SUNI revision number */
-#define SUNI_MRI_ID_SHIFT 	0
-#define SUNI_MRI_TYPE		0x70	/* R, SUNI type (lite is 011) */
-#define SUNI_MRI_TYPE_SHIFT 	4
-#define SUNI_MRI_TYPE_PM5346	0x3	/* S/UNI 155 LITE */
-#define SUNI_MRI_TYPE_PM5347	0x4	/* S/UNI 155 PLUS */
-#define SUNI_MRI_TYPE_PM5350	0x7	/* S/UNI 155 ULTRA */
-#define SUNI_MRI_TYPE_PM5355	0x1	/* S/UNI 622 */
-#define SUNI_MRI_RESET		0x80	/* RW, reset & power down chip
-					   0: normal operation
-					   1: reset & low power */
-
-/* MCM is reg 0x4 */
-#define SUNI_MCM_LLE		0x20	/* line loopback (PM5355) */
-#define SUNI_MCM_DLE		0x10	/* diagnostic loopback (PM5355) */
-
-/* MCT is reg 5 */
-#define SUNI_MCT_LOOPT		0x01	/* RW, timing source, 0: from
-					   TRCLK+/- */
-#define SUNI_MCT_DLE		0x02	/* RW, diagnostic loopback */
-#define SUNI_MCT_LLE		0x04	/* RW, line loopback */
-#define SUNI_MCT_FIXPTR		0x20	/* RW, disable transmit payload pointer
-					   adjustments
-					   0: payload ptr controlled by TPOP
-					      ptr control reg
-					   1: payload pointer fixed at 522 */
-#define SUNI_MCT_LCDV		0x40	/* R, loss of cell delineation */
-#define SUNI_MCT_LCDE		0x80	/* RW, loss of cell delineation
-					   interrupt (1: on) */
-/* RSOP_CIE is reg 0x10 */
-#define SUNI_RSOP_CIE_OOFE	0x01	/* RW, enable interrupt on frame alarm
-					   state change */
-#define SUNI_RSOP_CIE_LOFE	0x02	/* RW, enable interrupt on loss of
-					   frame state change */
-#define SUNI_RSOP_CIE_LOSE	0x04	/* RW, enable interrupt on loss of
-					   signal state change */
-#define SUNI_RSOP_CIE_BIPEE	0x08	/* RW, enable interrupt on section
-					   BIP-8 error (B1) */
-#define SUNI_RSOP_CIE_FOOF	0x20	/* W, force RSOP out of frame at next
-					   boundary */
-#define SUNI_RSOP_CIE_DDS	0x40	/* RW, disable scrambling */
-
-/* RSOP_SIS is reg 0x11 */
-#define SUNI_RSOP_SIS_OOFV	0x01	/* R, out of frame */
-#define SUNI_RSOP_SIS_LOFV	0x02	/* R, loss of frame */
-#define SUNI_RSOP_SIS_LOSV	0x04	/* R, loss of signal */
-#define SUNI_RSOP_SIS_OOFI	0x08	/* R, out of frame interrupt */
-#define SUNI_RSOP_SIS_LOFI	0x10	/* R, loss of frame interrupt */
-#define SUNI_RSOP_SIS_LOSI	0x20	/* R, loss of signal interrupt */
-#define SUNI_RSOP_SIS_BIPEI	0x40	/* R, section BIP-8 interrupt */
-
-/* TSOP_CTRL is reg 0x14 */
-#define SUNI_TSOP_CTRL_LAIS	0x01	/* insert alarm indication signal */
-#define SUNI_TSOP_CTRL_DS	0x40	/* disable scrambling */
-
-/* TSOP_DIAG is reg 0x15 */
-#define SUNI_TSOP_DIAG_DFP	0x01	/* insert single bit error cont. */
-#define SUNI_TSOP_DIAG_DBIP8	0x02	/* insert section BIP err (cont) */
-#define SUNI_TSOP_DIAG_DLOS	0x04	/* set line to zero (loss of signal) */
-
-/* TLOP_DIAG is reg 0x21 */
-#define SUNI_TLOP_DIAG_DBIP	0x01	/* insert line BIP err (continuously) */
-
-/* SSTB_CTRL is reg 0x28 */
-#define SUNI_SSTB_CTRL_LEN16	0x01	/* path trace message length bit */
-
-/* RPOP_RC is reg 0x3D (PM5355) */
-#define SUNI_RPOP_RC_ENSS	0x40	/* enable size bit */
-
-/* TPOP_DIAG is reg 0x40 */
-#define SUNI_TPOP_DIAG_PAIS	0x01	/* insert STS path alarm ind (cont) */
-#define SUNI_TPOP_DIAG_DB3	0x02	/* insert path BIP err (continuously) */
-
-/* TPOP_APM is reg 0x46 */
-#define SUNI_TPOP_APM_APTR	0x03	/* RW, arbitrary pointer, upper 2
-					   bits */
-#define SUNI_TPOP_APM_APTR_SHIFT 0
-#define SUNI_TPOP_APM_S		0x0c	/* RW, "unused" bits of payload
-					   pointer */
-#define SUNI_TPOP_APM_S_SHIFT	2
-#define SUNI_TPOP_APM_NDF	0xf0	 /* RW, NDF bits */
-#define SUNI_TPOP_APM_NDF_SHIFT	4
-
-#define SUNI_TPOP_S_SONET	0	/* set S bits to 00 */
-#define SUNI_TPOP_S_SDH		2	/* set S bits to 10 */
-
-/* RACP_IES is reg 0x51 */
-#define SUNI_RACP_IES_FOVRI	0x02	/* R, FIFO overrun */
-#define SUNI_RACP_IES_UHCSI	0x04	/* R, uncorrectable HCS error */
-#define SUNI_RACP_IES_CHCSI	0x08	/* R, correctable HCS error */
-#define SUNI_RACP_IES_OOCDI	0x10	/* R, change of cell delineation
-					   state */
-#define SUNI_RACP_IES_FIFOE	0x20	/* RW, enable FIFO overrun interrupt */
-#define SUNI_RACP_IES_HCSE	0x40	/* RW, enable HCS error interrupt */
-#define SUNI_RACP_IES_OOCDE	0x80	/* RW, enable cell delineation state
-					   change interrupt */
-
-/* TACP_CS is reg 0x60 */
-#define SUNI_TACP_CS_FIFORST	0x01	/* RW, reset transmit FIFO (sticky) */
-#define SUNI_TACP_CS_DSCR	0x02	/* RW, disable payload scrambling */
-#define SUNI_TACP_CS_HCAADD	0x04	/* RW, add coset polynomial to HCS */
-#define SUNI_TACP_CS_DHCS	0x10	/* RW, insert HCS errors */
-#define SUNI_TACP_CS_FOVRI	0x20	/* R, FIFO overrun */
-#define SUNI_TACP_CS_TSOCI	0x40	/* R, TSOC input high */
-#define SUNI_TACP_CS_FIFOE	0x80	/* RW, enable FIFO overrun interrupt */
-
-/* TACP_IUCHP is reg 0x61 */
-#define SUNI_TACP_IUCHP_CLP	0x01	/* RW, 8th bit of 4th octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_PTI	0x0e	/* RW, 5th-7th bits of 4th octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_PTI_SHIFT 1
-#define SUNI_TACP_IUCHP_GFC	0xf0	/* RW, 1st-4th bits of 1st octet of i/u
-					   pattern */
-#define SUNI_TACP_IUCHP_GFC_SHIFT 4
-
-/* SPTB_CTRL is reg 0x68 */
-#define SUNI_SPTB_CTRL_LEN16	0x01	/* path trace message length */
-
-/* MT is reg 0x80 */
-#define SUNI_MT_HIZIO		0x01	/* RW, all but data bus & MP interface
-					   tri-state */
-#define SUNI_MT_HIZDATA		0x02	/* W, also tri-state data bus */
-#define SUNI_MT_IOTST		0x04	/* RW, enable test mode */
-#define SUNI_MT_DBCTRL		0x08	/* W, control data bus by CSB pin */
-#define SUNI_MT_PMCTST		0x10	/* W, PMC test mode */
-#define SUNI_MT_DS27_53		0x80	/* RW, select between 8- or 16- bit */
-
-
-#define SUNI_IDLE_PATTERN       0x6a    /* idle pattern */
-
-
-#ifdef __KERNEL__
-struct suni_priv {
-	struct k_sonet_stats sonet_stats;	/* link diagnostics */
-	int loop_mode;				/* loopback mode */
-	int type;				/* phy type */
-	struct atm_dev *dev;			/* device back-pointer */
-	struct suni_priv *next;			/* next SUNI */
-};
-
-int suni_init(struct atm_dev *dev);
-#endif
-
-#endif
diff --git a/drivers/atm/tonga.h b/drivers/atm/tonga.h
deleted file mode 100644
index 771b3f9..0000000
--- a/drivers/atm/tonga.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/tonga.h - Efficient Networks Tonga (PCI bridge) declarations */
- 
-/* Written 1995 by Werner Almesberger, EPFL LRC */
- 
-
-#ifndef DRIVER_ATM_TONGA_H
-#define DRIVER_ATM_TONGA_H
-
-#define PCI_TONGA_CTRL	0x60	/* control register */
-
-#define END_SWAP_DMA	0x80	/* endian swap on DMA */
-#define END_SWAP_BYTE	0x40	/* endian swap on slave byte accesses */
-#define END_SWAP_WORD	0x20	/* endian swap on slave word accesses */
-#define SEPROM_MAGIC	0x0c	/* obscure required pattern (ASIC only) */
-#define SEPROM_DATA	0x02	/* serial EEPROM data (ASIC only) */
-#define SEPROM_CLK	0x01	/* serial EEPROM clock (ASIC only) */
-
-#define SEPROM_ESI_BASE	64	/* start of ESI in serial EEPROM */
-
-#endif
diff --git a/drivers/atm/zeprom.h b/drivers/atm/zeprom.h
deleted file mode 100644
index 8e8819a..0000000
--- a/drivers/atm/zeprom.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* drivers/atm/zeprom.h - ZeitNet ZN122x EEPROM (NM93C46) declarations */
-
-/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
-
-
-#ifndef DRIVER_ATM_ZEPROM_H
-#define DRIVER_ATM_ZEPROM_H
-
-/* Different versions use different control registers */
-
-#define ZEPROM_V1_REG	PCI_VENDOR_ID	/* PCI register */
-#define ZEPROM_V2_REG	0x40
-
-/* Bits in control register */
-
-#define ZEPROM_SK	0x80000000	/* strobe (probably on raising edge) */
-#define ZEPROM_CS	0x40000000	/* Chip Select */
-#define ZEPROM_DI	0x20000000	/* Data Input */
-#define ZEPROM_DO	0x10000000	/* Data Output */
-
-#define ZEPROM_SIZE	32		/* 32 bytes */
-#define ZEPROM_V1_ESI_OFF 24		/* ESI offset in EEPROM (V1) */
-#define ZEPROM_V2_ESI_OFF 4		/* ESI offset in EEPROM (V2) */
-
-#define ZEPROM_CMD_LEN	3		/* commands are three bits */
-#define ZEPROM_ADDR_LEN	6		/* addresses are six bits */
-
-/* Commands (3 bits) */
-
-#define ZEPROM_CMD_READ	6
-
-/* No other commands are needed. */
-
-#endif
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 673d709..bd2ddf2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -3688,6 +3688,21 @@ int device_add(struct device *dev)
 		fw_devlink_link_device(dev);
 	}
 
+	/*
+	 * The moment the device was linked into the bus's "klist_devices" in
+	 * bus_add_device() then it's possible that probe could have been
+	 * attempted in a different thread via userspace loading a driver
+	 * matching the device. "ready_to_probe" being unset would have
+	 * blocked those attempts. Now that all of the above initialization has
+	 * happened, unblock probe. If probe happens through another thread
+	 * after this point but before bus_probe_device() runs then it's fine.
+	 * bus_probe_device() -> device_initial_probe() -> __device_attach()
+	 * will notice (under device_lock) that the device is already bound.
+	 */
+	device_lock(dev);
+	dev_set_ready_to_probe(dev);
+	device_unlock(dev);
+
 	bus_probe_device(dev);
 
 	/*
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index cb5046f..1dc1e35 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -836,6 +836,26 @@ static int __driver_probe_device(const struct device_driver *drv, struct device
 	if (dev->driver)
 		return -EBUSY;
 
+	/*
+	 * In device_add(), the "struct device" gets linked into the subsystem's
+	 * list of devices and broadcast to userspace (via uevent) before we're
+	 * quite ready to probe. Those open pathways to driver probe before
+	 * we've finished enough of device_add() to reliably support probe.
+	 * Detect this and tell other pathways to try again later. device_add()
+	 * itself will also try to probe immediately after setting
+	 * "ready_to_probe".
+	 */
+	if (!dev_ready_to_probe(dev))
+		return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n");
+
+	/*
+	 * Set can_match = true after calling dev_ready_to_probe(), so
+	 * driver_deferred_probe_add() won't actually add the device to the
+	 * deferred probe list when dev_ready_to_probe() returns false.
+	 *
+	 * When dev_ready_to_probe() returns false, it means that device_add()
+	 * will do another probe() attempt for us.
+	 */
 	dev->can_match = true;
 	dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n",
 		drv->bus->name, __func__, drv->name);
diff --git a/drivers/base/property.c b/drivers/base/property.c
index d16e9c5..8e0148a 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -602,6 +602,8 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_property_string);
  *	    %-ENOENT when the index is out of bounds, the index has an empty
  *		     reference or the property was not found
  *	    %-EINVAL on parse error
+ *	    %-ENOTCONN when the remote firmware node exists but has not been
+ *		       registered yet
  */
 int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
 				       const char *prop, const char *nargs_prop,
diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c
index c9b39a0..31e30df 100644
--- a/drivers/base/regmap/regmap-i2c.c
+++ b/drivers/base/regmap/regmap-i2c.c
@@ -303,6 +303,50 @@ static const struct regmap_bus regmap_i2c_smbus_i2c_block_reg16 = {
 	.max_raw_write = I2C_SMBUS_BLOCK_MAX - 2,
 };
 
+/*
+ * SMBus byte/word reg16 support for adapters that have SMBUS_BYTE_DATA
+ * and SMBUS_WORD_DATA but lack I2C_FUNC_I2C and I2C_FUNC_SMBUS_I2C_BLOCK,
+ * such as the AMD PIIX4.
+ *
+ * READ:  set 16-bit EEPROM address via write_byte_data(addr_lo, addr_hi),
+ *        then sequentially read bytes via read_byte() (EEPROM auto-
+ *        increments the address pointer).  Same as the I2C-block reg16
+ *        read path above.
+ *
+ * WRITE: encode the low address byte and data into a word transaction:
+ *        write_word_data(addr_hi, (data_byte << 8) | addr_lo).
+ *        Only single-byte writes are supported (one value per transaction).
+ */
+static int regmap_smbus_word_write_reg16(void *context, const void *data,
+					 size_t count)
+{
+	struct device *dev = context;
+	struct i2c_client *i2c = to_i2c_client(dev);
+	u8 addr_hi, addr_lo, val;
+
+	/*
+	 * data layout: [addr_hi, addr_lo, val0, val1, ...].
+	 * Only single-byte value writes are supported; multi-byte would
+	 * require raw I2C (or repeated word writes with incrementing address).
+	 */
+	if (count != 3)
+		return -EINVAL;
+
+	addr_hi = ((u8 *)data)[0];
+	addr_lo = ((u8 *)data)[1];
+	val = ((u8 *)data)[2];
+
+	return i2c_smbus_write_word_data(i2c, addr_hi,
+					 cpu_to_le16(((u16)val << 8) | addr_lo));
+}
+
+static const struct regmap_bus regmap_smbus_byte_word_reg16 = {
+	.write = regmap_smbus_word_write_reg16,
+	.read = regmap_i2c_smbus_i2c_read_reg16,
+	.max_raw_read = I2C_SMBUS_BLOCK_MAX - 2,
+	.max_raw_write = 1,
+};
+
 static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 					const struct regmap_config *config)
 {
@@ -321,6 +365,11 @@ static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
 		i2c_check_functionality(i2c->adapter,
 					I2C_FUNC_SMBUS_I2C_BLOCK))
 		bus = &regmap_i2c_smbus_i2c_block_reg16;
+	else if (config->val_bits == 8 && config->reg_bits == 16 &&
+		 i2c_check_functionality(i2c->adapter,
+					I2C_FUNC_SMBUS_BYTE_DATA |
+					I2C_FUNC_SMBUS_WORD_DATA))
+		bus = &regmap_smbus_byte_word_reg16;
 	else if (config->val_bits == 16 && config->reg_bits == 8 &&
 		 i2c_check_functionality(i2c->adapter,
 					 I2C_FUNC_SMBUS_WORD_DATA))
diff --git a/drivers/base/regmap/regmap-ram.c b/drivers/base/regmap/regmap-ram.c
index 0272d53..c7356b0 100644
--- a/drivers/base/regmap/regmap-ram.c
+++ b/drivers/base/regmap/regmap-ram.c
@@ -71,11 +71,17 @@ struct regmap *__regmap_init_ram(struct device *dev,
 		return ERR_PTR(-ENOMEM);
 
 	data->written = kzalloc_objs(bool, config->max_register + 1);
-	if (!data->written)
+	if (!data->written) {
+		kfree(data->read);
 		return ERR_PTR(-ENOMEM);
+	}
 
 	map = __regmap_init(dev, &regmap_ram, data, config,
 			    lock_key, lock_name);
+	if (IS_ERR(map)) {
+		kfree(data->read);
+		kfree(data->written);
+	}
 
 	return map;
 }
diff --git a/drivers/base/regmap/regmap-sdw-mbq.c b/drivers/base/regmap/regmap-sdw-mbq.c
index 6a61629..4533fe7 100644
--- a/drivers/base/regmap/regmap-sdw-mbq.c
+++ b/drivers/base/regmap/regmap-sdw-mbq.c
@@ -74,7 +74,7 @@ static int regmap_sdw_mbq_poll_busy(struct sdw_slave *slave, unsigned int reg,
 
 static int regmap_sdw_mbq_write_impl(struct sdw_slave *slave,
 				     unsigned int reg, unsigned int val,
-				     int mbq_size, bool deferrable)
+				     int mbq_size)
 {
 	int shift = mbq_size * BITS_PER_BYTE;
 	int ret;
@@ -88,17 +88,14 @@ static int regmap_sdw_mbq_write_impl(struct sdw_slave *slave,
 			return ret;
 	}
 
-	ret = sdw_write_no_pm(slave, reg, val & 0xff);
-	if (deferrable && ret == -ENODATA)
-		return -EAGAIN;
-
-	return ret;
+	return sdw_write_no_pm(slave, reg, val & 0xff);
 }
 
 static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int val)
 {
 	struct regmap_mbq_context *ctx = context;
 	struct sdw_slave *slave = ctx->sdw;
+	struct device *dev = ctx->dev;
 	bool deferrable = regmap_sdw_mbq_deferrable(ctx, reg);
 	int mbq_size = regmap_sdw_mbq_size(ctx, reg);
 	int ret;
@@ -113,13 +110,16 @@ static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int va
 	 * process a single wait/timeout on function busy and a single retry
 	 * of the transaction.
 	 */
-	ret = regmap_sdw_mbq_write_impl(slave, reg, val, mbq_size, deferrable);
-	if (ret == -EAGAIN) {
+	ret = regmap_sdw_mbq_write_impl(slave, reg, val, mbq_size);
+	if (ret == -ENODATA) {
+		if (!deferrable)
+			dev_warn(dev, "Defer on undeferrable control: %x\n", reg);
+
 		ret = regmap_sdw_mbq_poll_busy(slave, reg, ctx);
 		if (ret)
 			return ret;
 
-		ret = regmap_sdw_mbq_write_impl(slave, reg, val, mbq_size, false);
+		ret = regmap_sdw_mbq_write_impl(slave, reg, val, mbq_size);
 	}
 
 	return ret;
@@ -127,18 +127,14 @@ static int regmap_sdw_mbq_write(void *context, unsigned int reg, unsigned int va
 
 static int regmap_sdw_mbq_read_impl(struct sdw_slave *slave,
 				    unsigned int reg, unsigned int *val,
-				    int mbq_size, bool deferrable)
+				    int mbq_size)
 {
 	int shift = BITS_PER_BYTE;
 	int read;
 
 	read = sdw_read_no_pm(slave, reg);
-	if (read < 0) {
-		if (deferrable && read == -ENODATA)
-			return -EAGAIN;
-
+	if (read < 0)
 		return read;
-	}
 
 	*val = read;
 
@@ -158,6 +154,7 @@ static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *va
 {
 	struct regmap_mbq_context *ctx = context;
 	struct sdw_slave *slave = ctx->sdw;
+	struct device *dev = ctx->dev;
 	bool deferrable = regmap_sdw_mbq_deferrable(ctx, reg);
 	int mbq_size = regmap_sdw_mbq_size(ctx, reg);
 	int ret;
@@ -172,13 +169,16 @@ static int regmap_sdw_mbq_read(void *context, unsigned int reg, unsigned int *va
 	 * process a single wait/timeout on function busy and a single retry
 	 * of the transaction.
 	 */
-	ret = regmap_sdw_mbq_read_impl(slave, reg, val, mbq_size, deferrable);
-	if (ret == -EAGAIN) {
+	ret = regmap_sdw_mbq_read_impl(slave, reg, val, mbq_size);
+	if (ret == -ENODATA) {
+		if (!deferrable)
+			dev_warn(dev, "Defer on undeferable control: %x\n", reg);
+
 		ret = regmap_sdw_mbq_poll_busy(slave, reg, ctx);
 		if (ret)
 			return ret;
 
-		ret = regmap_sdw_mbq_read_impl(slave, reg, val, mbq_size, false);
+		ret = regmap_sdw_mbq_read_impl(slave, reg, val, mbq_size);
 	}
 
 	return ret;
diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
index a80575b..a19f8f7 100644
--- a/drivers/base/swnode.c
+++ b/drivers/base/swnode.c
@@ -554,7 +554,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
 		return -EINVAL;
 
 	if (!refnode)
-		return -ENOENT;
+		return -ENOTCONN;
 
 	if (nargs_prop) {
 		error = fwnode_property_read_u32(refnode, nargs_prop, &nargs_prop_val);
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index c2afd1c..aebc710 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -2546,6 +2546,8 @@ static ssize_t recompress_store(struct device *dev,
 				mode = RECOMPRESS_HUGE;
 			if (!strcmp(val, "huge_idle"))
 				mode = RECOMPRESS_IDLE | RECOMPRESS_HUGE;
+			if (!mode)
+				return -EINVAL;
 			continue;
 		}
 
@@ -2678,7 +2680,7 @@ static void zram_bio_discard(struct zram *zram, struct bio *bio)
 	 */
 	if (offset) {
 		if (n <= (PAGE_SIZE - offset))
-			return;
+			goto end_bio;
 
 		n -= (PAGE_SIZE - offset);
 		index++;
@@ -2693,6 +2695,7 @@ static void zram_bio_discard(struct zram *zram, struct bio *bio)
 		n -= PAGE_SIZE;
 	}
 
+end_bio:
 	bio_endio(bio);
 }
 
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
index e3d0a3c..0277e1a 100644
--- a/drivers/bus/mhi/ep/main.c
+++ b/drivers/bus/mhi/ep/main.c
@@ -367,7 +367,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info)
 				ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el,
 							     MHI_TRE_DATA_GET_LEN(el),
 							     MHI_EV_CC_EOB);
-				if (ret < 0) {
+				if (ret) {
 					dev_err(&mhi_chan->mhi_dev->dev,
 						"Error sending transfer compl. event\n");
 					goto err_free_tre_buf;
@@ -383,7 +383,7 @@ static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info)
 				ret = mhi_ep_send_completion_event(mhi_cntrl, ring, el,
 							     MHI_TRE_DATA_GET_LEN(el),
 							     MHI_EV_CC_EOT);
-				if (ret < 0) {
+				if (ret) {
 					dev_err(&mhi_chan->mhi_dev->dev,
 						"Error sending transfer compl. event\n");
 					goto err_free_tre_buf;
@@ -449,7 +449,7 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl,
 
 		dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_id);
 		ret = mhi_cntrl->read_async(mhi_cntrl, &buf_info);
-		if (ret < 0) {
+		if (ret) {
 			dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n");
 			goto err_free_buf_addr;
 		}
@@ -494,7 +494,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring)
 	} else {
 		/* UL channel */
 		ret = mhi_ep_read_channel(mhi_cntrl, ring);
-		if (ret < 0) {
+		if (ret) {
 			dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n");
 			return ret;
 		}
@@ -591,7 +591,7 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
 
 		dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id);
 		ret = mhi_cntrl->write_async(mhi_cntrl, &buf_info);
-		if (ret < 0) {
+		if (ret) {
 			dev_err(dev, "Error writing to the channel\n");
 			goto err_exit;
 		}
diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c
index 9375b16..405ce16 100644
--- a/drivers/bus/mhi/ep/ring.c
+++ b/drivers/bus/mhi/ep/ring.c
@@ -49,7 +49,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
 		buf_info.dev_addr = &ring->ring_cache[start];
 
 		ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
-		if (ret < 0)
+		if (ret)
 			return ret;
 	} else {
 		buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element);
@@ -57,7 +57,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
 		buf_info.dev_addr = &ring->ring_cache[start];
 
 		ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
-		if (ret < 0)
+		if (ret)
 			return ret;
 
 		if (end) {
@@ -66,7 +66,7 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
 			buf_info.size = end * sizeof(struct mhi_ring_element);
 
 			ret = mhi_cntrl->read_sync(mhi_cntrl, &buf_info);
-			if (ret < 0)
+			if (ret)
 				return ret;
 		}
 	}
diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c
index f16a1e6..19c8491 100644
--- a/drivers/bus/mhi/host/boot.c
+++ b/drivers/bus/mhi/host/boot.c
@@ -308,7 +308,6 @@ static void mhi_free_bhi_buffer(struct mhi_controller *mhi_cntrl,
 	struct mhi_buf *mhi_buf = image_info->mhi_buf;
 
 	dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr);
-	kfree(image_info->mhi_buf);
 	kfree(image_info);
 }
 
@@ -322,7 +321,6 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
 		dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
 				  mhi_buf->buf, mhi_buf->dma_addr);
 
-	kfree(image_info->mhi_buf);
 	kfree(image_info);
 }
 
@@ -333,15 +331,10 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl,
 	struct image_info *img_info;
 	struct mhi_buf *mhi_buf;
 
-	img_info = kzalloc_obj(*img_info);
+	img_info = kzalloc_flex(*img_info, mhi_buf, 1);
 	if (!img_info)
 		return -ENOMEM;
 
-	/* Allocate memory for entry */
-	img_info->mhi_buf = kzalloc_obj(*img_info->mhi_buf);
-	if (!img_info->mhi_buf)
-		goto error_alloc_mhi_buf;
-
 	/* Allocate and populate vector table */
 	mhi_buf = img_info->mhi_buf;
 
@@ -358,8 +351,6 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl,
 	return 0;
 
 error_alloc_segment:
-	kfree(mhi_buf);
-error_alloc_mhi_buf:
 	kfree(img_info);
 
 	return -ENOMEM;
@@ -375,14 +366,11 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
 	struct image_info *img_info;
 	struct mhi_buf *mhi_buf;
 
-	img_info = kzalloc_obj(*img_info);
+	img_info = kzalloc_flex(*img_info, mhi_buf, segments);
 	if (!img_info)
 		return -ENOMEM;
 
-	/* Allocate memory for entries */
-	img_info->mhi_buf = kzalloc_objs(*img_info->mhi_buf, segments);
-	if (!img_info->mhi_buf)
-		goto error_alloc_mhi_buf;
+	img_info->entries = segments;
 
 	/* Allocate and populate vector table */
 	mhi_buf = img_info->mhi_buf;
@@ -402,7 +390,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
 	}
 
 	img_info->bhi_vec = img_info->mhi_buf[segments - 1].buf;
-	img_info->entries = segments;
 	*image_info = img_info;
 
 	return 0;
@@ -411,9 +398,6 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl,
 	for (--i, --mhi_buf; i >= 0; i--, mhi_buf--)
 		dma_free_coherent(mhi_cntrl->cntrl_dev, mhi_buf->len,
 				  mhi_buf->buf, mhi_buf->dma_addr);
-	kfree(img_info->mhi_buf);
-
-error_alloc_mhi_buf:
 	kfree(img_info);
 
 	return -ENOMEM;
diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c
index 0884a38..750da3d 100644
--- a/drivers/bus/mhi/host/pci_generic.c
+++ b/drivers/bus/mhi/host/pci_generic.c
@@ -253,6 +253,13 @@ static const struct mhi_channel_config mhi_qcom_qdu100_channels[] = {
 	MHI_CHANNEL_CONFIG_DL(41, "MHI_PHC", 32, 4),
 	MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 256, 5),
 	MHI_CHANNEL_CONFIG_DL(47, "IP_SW0", 256, 5),
+	MHI_CHANNEL_CONFIG_UL(48, "IP_SW1", 256, 6),
+	MHI_CHANNEL_CONFIG_DL(49, "IP_SW1", 256, 6),
+	MHI_CHANNEL_CONFIG_UL(50, "IP_ETH0", 256, 7),
+	MHI_CHANNEL_CONFIG_DL(51, "IP_ETH0", 256, 7),
+	MHI_CHANNEL_CONFIG_UL(52, "IP_ETH1", 256, 8),
+	MHI_CHANNEL_CONFIG_DL(53, "IP_ETH1", 256, 8),
+
 };
 
 static struct mhi_event_config mhi_qcom_qdu100_events[] = {
@@ -268,6 +275,7 @@ static struct mhi_event_config mhi_qcom_qdu100_events[] = {
 	MHI_EVENT_CONFIG_SW_DATA(5, 512),
 	MHI_EVENT_CONFIG_SW_DATA(6, 512),
 	MHI_EVENT_CONFIG_SW_DATA(7, 512),
+	MHI_EVENT_CONFIG_SW_DATA(8, 512),
 };
 
 static const struct mhi_controller_config mhi_qcom_qdu100_config = {
@@ -407,6 +415,16 @@ static const struct mhi_pci_dev_info mhi_qcom_sdx55_info = {
 	.sideband_wake = false,
 };
 
+static const struct mhi_pci_dev_info mhi_qcom_sdx35_info = {
+	.name = "qcom-sdx35m",
+	.config = &modem_qcom_v2_mhiv_config,
+	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
+	.dma_data_width = 32,
+	.mru_default = 32768,
+	.sideband_wake = false,
+	.edl_trigger = true,
+};
+
 static const struct mhi_pci_dev_info mhi_qcom_sdx24_info = {
 	.name = "qcom-sdx24",
 	.edl = "qcom/prog_firehose_sdx24.mbn",
@@ -788,6 +806,8 @@ static const struct mhi_channel_config mhi_telit_fn990_channels[] = {
 	MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0),
 	MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),
 	MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),
+	MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1),
+	MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1),
 	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0_MBIM", 128, 2),
 	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0_MBIM", 128, 3),
 };
@@ -839,6 +859,8 @@ static const struct mhi_channel_config mhi_telit_fn920c04_channels[] = {
 	MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0),
 	MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1),
 	MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1),
+	MHI_CHANNEL_CONFIG_UL(94, "NMEA", 32, 1),
+	MHI_CHANNEL_CONFIG_DL(95, "NMEA", 32, 1),
 	MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2),
 	MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3),
 };
@@ -882,6 +904,16 @@ static const struct mhi_pci_dev_info mhi_telit_fe990b40_info = {
 	.edl_trigger = true,
 };
 
+static const struct mhi_pci_dev_info mhi_telit_fe912c04_info = {
+	.name = "telit-fe912c04",
+	.config = &modem_telit_fn920c04_config,
+	.bar_num = MHI_PCI_DEFAULT_BAR_NUM,
+	.dma_data_width = 32,
+	.sideband_wake = false,
+	.mru_default = 32768,
+	.edl_trigger = true,
+};
+
 static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = {
 	.name = "netprisma-lcur57",
 	.edl = "qcom/prog_firehose_sdx24.mbn",
@@ -909,6 +941,11 @@ static const struct pci_device_id mhi_pci_id_table[] = {
 	/* Telit FN920C04 (sdx35) */
 	{PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2020),
 		.driver_data = (kernel_ulong_t) &mhi_telit_fn920c04_info },
+	/* Telit FE912C04 (sdx35) */
+	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2045),
+		.driver_data = (kernel_ulong_t) &mhi_telit_fe912c04_info },
+	{ PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x011a),
+		.driver_data = (kernel_ulong_t) &mhi_qcom_sdx35_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),
@@ -1393,7 +1430,7 @@ static int mhi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 		goto err_unregister;
 	}
 
-	err = mhi_sync_power_up(mhi_cntrl);
+	err = mhi_async_power_up(mhi_cntrl);
 	if (err) {
 		dev_err(&pdev->dev, "failed to power up MHI controller\n");
 		goto err_unprepare;
@@ -1428,6 +1465,7 @@ static void mhi_pci_remove(struct pci_dev *pdev)
 	struct mhi_pci_device *mhi_pdev = pci_get_drvdata(pdev);
 	struct mhi_controller *mhi_cntrl = &mhi_pdev->mhi_cntrl;
 
+	pm_runtime_forbid(&pdev->dev);
 	pci_disable_sriov(pdev);
 
 	if (pdev->is_physfn)
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 4d920ca..8983add 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -323,18 +323,6 @@ int agp_try_unsupported_boot;
 EXPORT_SYMBOL(agp_off);
 EXPORT_SYMBOL(agp_try_unsupported_boot);
 
-static int __init agp_init(void)
-{
-	if (!agp_off)
-		printk(KERN_INFO "Linux agpgart interface v%d.%d\n",
-			AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
-	return 0;
-}
-
-static void __exit agp_exit(void)
-{
-}
-
 #ifndef MODULE
 static __init int agp_setup(char *s)
 {
@@ -351,7 +339,3 @@ MODULE_AUTHOR("Dave Jones, Jeff Hartmann");
 MODULE_DESCRIPTION("AGP GART driver");
 MODULE_LICENSE("GPL and additional rights");
 MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
-
-module_init(agp_init);
-module_exit(agp_exit);
-
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 8f128cc..46c84e5 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -34,6 +34,7 @@
 #include <linux/io.h>
 #include <linux/acpi.h>
 #include <linux/hpet.h>
+#include <linux/platform_device.h>
 #include <asm/current.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
@@ -973,8 +974,9 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
 	return AE_OK;
 }
 
-static int hpet_acpi_add(struct acpi_device *device)
+static int hpet_acpi_probe(struct platform_device *pdev)
 {
+	struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
 	acpi_status result;
 	struct hpet_data data;
 
@@ -1002,12 +1004,12 @@ static const struct acpi_device_id hpet_device_ids[] = {
 	{"", 0},
 };
 
-static struct acpi_driver hpet_acpi_driver = {
-	.name = "hpet",
-	.ids = hpet_device_ids,
-	.ops = {
-		.add = hpet_acpi_add,
-		},
+static struct platform_driver hpet_acpi_driver = {
+	.probe = hpet_acpi_probe,
+	.driver = {
+		.name = "hpet_acpi",
+		.acpi_match_table = hpet_device_ids,
+	},
 };
 
 static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
@@ -1022,7 +1024,7 @@ static int __init hpet_init(void)
 
 	sysctl_header = register_sysctl("dev/hpet", hpet_table);
 
-	result = acpi_bus_register_driver(&hpet_acpi_driver);
+	result = platform_driver_register(&hpet_acpi_driver);
 	if (result < 0) {
 		unregister_sysctl_table(sysctl_header);
 		misc_deregister(&hpet_misc);
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 92bed26..669f760 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -187,6 +187,16 @@
 	  The driver implements the BMC side of the SMBus system
 	  interface (SSIF).
 
+config SSIF_IPMI_BMC_KUNIT_TEST
+	bool "KUnit tests for SSIF IPMI BMC driver" if !KUNIT_ALL_TESTS
+	depends on KUNIT=y
+	depends on SSIF_IPMI_BMC
+	default KUNIT_ALL_TESTS
+	help
+	  This option builds unit tests that exercise the SSIF BMC state
+	  machine, including request handling, response transmission,
+	  and error paths such as aborted or truncated transfers.
+
 config IPMB_DEVICE_INTERFACE
 	tristate 'IPMB Interface handler'
 	depends on I2C
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index c41f51c..869ac87 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -987,7 +987,7 @@ static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
 		mutex_lock(&intf->user_msgs_mutex);
 		list_add_tail(&msg->link, &intf->user_msgs);
 		mutex_unlock(&intf->user_msgs_mutex);
-		queue_work(system_wq, &intf->smi_work);
+		queue_work(system_percpu_wq, &intf->smi_work);
 	}
 
 	return rv;
@@ -4977,7 +4977,7 @@ void ipmi_smi_msg_received(struct ipmi_smi *intf,
 	if (run_to_completion)
 		smi_work(&intf->smi_work);
 	else
-		queue_work(system_wq, &intf->smi_work);
+		queue_work(system_percpu_wq, &intf->smi_work);
 }
 EXPORT_SYMBOL(ipmi_smi_msg_received);
 
@@ -4987,7 +4987,7 @@ void ipmi_smi_watchdog_pretimeout(struct ipmi_smi *intf)
 		return;
 
 	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 1);
-	queue_work(system_wq, &intf->smi_work);
+	queue_work(system_percpu_wq, &intf->smi_work);
 }
 EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout);
 
@@ -5162,7 +5162,7 @@ static bool ipmi_timeout_handler(struct ipmi_smi *intf,
 				       flags);
 	}
 
-	queue_work(system_wq, &intf->smi_work);
+	queue_work(system_percpu_wq, &intf->smi_work);
 
 	return need_timer;
 }
@@ -5218,7 +5218,7 @@ static void ipmi_timeout(struct timer_list *unused)
 	if (atomic_read(&stop_operation))
 		return;
 
-	queue_work(system_wq, &ipmi_timer_work);
+	queue_work(system_percpu_wq, &ipmi_timer_work);
 }
 
 static void need_waiter(struct ipmi_smi *intf)
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 37a5cb5..b49500a 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -1268,8 +1268,10 @@ static void shutdown_ssif(void *send_info)
 	ssif_info->stopping = true;
 	timer_delete_sync(&ssif_info->watch_timer);
 	timer_delete_sync(&ssif_info->retry_timer);
-	if (ssif_info->thread)
+	if (ssif_info->thread) {
 		kthread_stop(ssif_info->thread);
+		ssif_info->thread = NULL;
+	}
 }
 
 static void ssif_remove(struct i2c_client *client)
@@ -1658,6 +1660,7 @@ static int ssif_probe(struct i2c_client *client)
 	int               len = 0;
 	int               i;
 	u8		  slave_addr = 0;
+	unsigned int      thread_num;
 	struct ssif_addr_info *addr_info = NULL;
 
 	mutex_lock(&ssif_infos_mutex);
@@ -1876,22 +1879,17 @@ static int ssif_probe(struct i2c_client *client)
 	ssif_info->handlers.request_events = request_events;
 	ssif_info->handlers.set_need_watch = ssif_set_need_watch;
 
-	{
-		unsigned int thread_num;
-
-		thread_num = ((i2c_adapter_id(ssif_info->client->adapter)
-			       << 8) |
-			      ssif_info->client->addr);
-		init_completion(&ssif_info->wake_thread);
-		ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info,
-					       "kssif%4.4x", thread_num);
-		if (IS_ERR(ssif_info->thread)) {
-			rv = PTR_ERR(ssif_info->thread);
-			dev_notice(&ssif_info->client->dev,
-				   "Could not start kernel thread: error %d\n",
-				   rv);
-			goto out;
-		}
+	thread_num = ((i2c_adapter_id(ssif_info->client->adapter) << 8) |
+		      ssif_info->client->addr);
+	init_completion(&ssif_info->wake_thread);
+	ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info,
+					"kssif%4.4x", thread_num);
+	if (IS_ERR(ssif_info->thread)) {
+		rv = PTR_ERR(ssif_info->thread);
+		dev_notice(&ssif_info->client->dev,
+			   "Could not start kernel thread: error %d\n",
+			   rv);
+		goto out;
 	}
 
 	dev_set_drvdata(&ssif_info->client->dev, ssif_info);
@@ -1916,6 +1914,15 @@ static int ssif_probe(struct i2c_client *client)
 
  out:
 	if (rv) {
+		/*
+		 * If ipmi_register_smi() starts the interface, it will
+		 * call shutdown and that will free the thread and set
+		 * it to NULL.  Otherwise it must be freed here.
+		 */
+		if (ssif_info->thread) {
+			kthread_stop(ssif_info->thread);
+			ssif_info->thread = NULL;
+		}
 		if (addr_info)
 			addr_info->client = NULL;
 
diff --git a/drivers/char/ipmi/ssif_bmc.c b/drivers/char/ipmi/ssif_bmc.c
index 7a52e3e..1df0e92 100644
--- a/drivers/char/ipmi/ssif_bmc.c
+++ b/drivers/char/ipmi/ssif_bmc.c
@@ -18,6 +18,9 @@
 #include <linux/timer.h>
 #include <linux/jiffies.h>
 #include <linux/ipmi_ssif_bmc.h>
+#if IS_ENABLED(CONFIG_SSIF_IPMI_BMC_KUNIT_TEST)
+#include <kunit/test.h>
+#endif
 
 #define DEVICE_NAME                             "ipmi-ssif-host"
 
@@ -163,6 +166,8 @@ static ssize_t ssif_bmc_read(struct file *file, char __user *buf, size_t count,
 		spin_unlock_irqrestore(&ssif_bmc->lock, flags);
 
 		ret = copy_to_user(buf, &msg, count);
+		if (ret > 0)
+			ret = -EFAULT;
 	}
 
 	return (ret < 0) ? ret : count;
@@ -456,6 +461,15 @@ static bool supported_write_cmd(u8 cmd)
 	return false;
 }
 
+static bool supported_write_start_cmd(u8 cmd)
+{
+	if (cmd == SSIF_IPMI_SINGLEPART_WRITE ||
+	    cmd == SSIF_IPMI_MULTIPART_WRITE_START)
+		return true;
+
+	return false;
+}
+
 /* Process the IPMI response that will be read by master */
 static void handle_read_processed(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 {
@@ -558,7 +572,7 @@ static void process_request_part(struct ssif_bmc_ctx *ssif_bmc)
 		len = ssif_bmc->request.len + part->length;
 		/* Do the bound check here, not allow the request len exceed 254 bytes */
 		if (len > IPMI_SSIF_PAYLOAD_MAX) {
-			dev_warn(&ssif_bmc->client->dev,
+			dev_dbg(&ssif_bmc->client->dev,
 				 "Warn: Request exceeded 254 bytes, aborting");
 			/* Request too long, aborting */
 			ssif_bmc->aborting =  true;
@@ -604,7 +618,7 @@ static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 	    ssif_bmc->state == SSIF_START ||
 	    ssif_bmc->state == SSIF_REQ_RECVING ||
 	    ssif_bmc->state == SSIF_RES_SENDING) {
-		dev_warn(&ssif_bmc->client->dev,
+		dev_dbg(&ssif_bmc->client->dev,
 			 "Warn: %s unexpected READ REQUESTED in state=%s\n",
 			 __func__, state_to_string(ssif_bmc->state));
 		ssif_bmc->state = SSIF_ABORTING;
@@ -613,7 +627,7 @@ static void on_read_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 
 	} else if (ssif_bmc->state == SSIF_SMBUS_CMD) {
 		if (!supported_read_cmd(ssif_bmc->part_buf.smbus_cmd)) {
-			dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus read command=0x%x",
+			dev_dbg(&ssif_bmc->client->dev, "Warn: Unknown SMBus read command=0x%x",
 				 ssif_bmc->part_buf.smbus_cmd);
 			ssif_bmc->aborting = true;
 		}
@@ -648,7 +662,7 @@ static void on_read_processed_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 	    ssif_bmc->state == SSIF_START ||
 	    ssif_bmc->state == SSIF_REQ_RECVING ||
 	    ssif_bmc->state == SSIF_SMBUS_CMD) {
-		dev_warn(&ssif_bmc->client->dev,
+		dev_dbg(&ssif_bmc->client->dev,
 			 "Warn: %s unexpected READ PROCESSED in state=%s\n",
 			 __func__, state_to_string(ssif_bmc->state));
 		ssif_bmc->state = SSIF_ABORTING;
@@ -673,7 +687,7 @@ static void on_write_requested_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 	} else if (ssif_bmc->state == SSIF_START ||
 		   ssif_bmc->state == SSIF_REQ_RECVING ||
 		   ssif_bmc->state == SSIF_RES_SENDING) {
-		dev_warn(&ssif_bmc->client->dev,
+		dev_dbg(&ssif_bmc->client->dev,
 			 "Warn: %s unexpected WRITE REQUEST in state=%s\n",
 			 __func__, state_to_string(ssif_bmc->state));
 		ssif_bmc->state = SSIF_ABORTING;
@@ -688,7 +702,7 @@ static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 {
 	if (ssif_bmc->state == SSIF_READY ||
 	    ssif_bmc->state == SSIF_RES_SENDING) {
-		dev_warn(&ssif_bmc->client->dev,
+		dev_dbg(&ssif_bmc->client->dev,
 			 "Warn: %s unexpected WRITE RECEIVED in state=%s\n",
 			 __func__, state_to_string(ssif_bmc->state));
 		ssif_bmc->state = SSIF_ABORTING;
@@ -698,7 +712,7 @@ static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 
 	} else if (ssif_bmc->state == SSIF_SMBUS_CMD) {
 		if (!supported_write_cmd(ssif_bmc->part_buf.smbus_cmd)) {
-			dev_warn(&ssif_bmc->client->dev, "Warn: Unknown SMBus write command=0x%x",
+			dev_dbg(&ssif_bmc->client->dev, "Warn: Unknown SMBus write command=0x%x",
 				 ssif_bmc->part_buf.smbus_cmd);
 			ssif_bmc->aborting = true;
 		}
@@ -707,6 +721,11 @@ static void on_write_received_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 			ssif_bmc->state = SSIF_ABORTING;
 		else
 			ssif_bmc->state = SSIF_REQ_RECVING;
+	} else if (ssif_bmc->state == SSIF_ABORTING) {
+		if (supported_write_start_cmd(*val)) {
+			ssif_bmc->state = SSIF_SMBUS_CMD;
+			ssif_bmc->aborting = false;
+		}
 	}
 
 	/* This is response sending state */
@@ -722,7 +741,7 @@ static void on_stop_event(struct ssif_bmc_ctx *ssif_bmc, u8 *val)
 	    ssif_bmc->state == SSIF_START ||
 	    ssif_bmc->state == SSIF_SMBUS_CMD ||
 	    ssif_bmc->state == SSIF_ABORTING) {
-		dev_warn(&ssif_bmc->client->dev,
+		dev_dbg(&ssif_bmc->client->dev,
 			 "Warn: %s unexpected SLAVE STOP in state=%s\n",
 			 __func__, state_to_string(ssif_bmc->state));
 		ssif_bmc->state = SSIF_READY;
@@ -789,7 +808,7 @@ static int ssif_bmc_cb(struct i2c_client *client, enum i2c_slave_event event, u8
 		break;
 
 	default:
-		dev_warn(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event\n");
+		dev_dbg(&ssif_bmc->client->dev, "Warn: Unknown i2c slave event\n");
 		break;
 	}
 
@@ -843,6 +862,7 @@ static void ssif_bmc_remove(struct i2c_client *client)
 {
 	struct ssif_bmc_ctx *ssif_bmc = i2c_get_clientdata(client);
 
+	timer_delete_sync(&ssif_bmc->response_timer);
 	i2c_slave_unregister(client);
 	misc_deregister(&ssif_bmc->miscdev);
 }
@@ -869,6 +889,373 @@ static struct i2c_driver ssif_bmc_driver = {
 	.id_table       = ssif_bmc_id,
 };
 
+#if IS_ENABLED(CONFIG_SSIF_IPMI_BMC_KUNIT_TEST)
+struct ssif_bmc_test_ctx {
+	struct ssif_bmc_ctx ssif_bmc;
+	struct i2c_client client;
+	struct i2c_adapter adapter;
+	struct i2c_algorithm algo;
+};
+
+static int ssif_bmc_test_init(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx;
+
+	test_ctx = kunit_kzalloc(test, sizeof(*test_ctx), GFP_KERNEL);
+	if (!test_ctx)
+		return -ENOMEM;
+
+	test_ctx->adapter.algo = &test_ctx->algo;
+	test_ctx->client.addr = 0x20;
+	test_ctx->client.adapter = &test_ctx->adapter;
+
+	spin_lock_init(&test_ctx->ssif_bmc.lock);
+	init_waitqueue_head(&test_ctx->ssif_bmc.wait_queue);
+	test_ctx->ssif_bmc.client = &test_ctx->client;
+	i2c_set_clientdata(&test_ctx->client, &test_ctx->ssif_bmc);
+
+	test->priv = test_ctx;
+
+	return 0;
+}
+
+static void ssif_bmc_test_exit(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+
+	if (test_ctx->ssif_bmc.response_timer_inited)
+		timer_delete_sync(&test_ctx->ssif_bmc.response_timer);
+}
+
+static int ssif_bmc_test_run_event_val(struct ssif_bmc_test_ctx *test_ctx,
+					       enum i2c_slave_event event,
+					       u8 *value)
+{
+	return ssif_bmc_cb(&test_ctx->client, event, value);
+}
+
+static int ssif_bmc_test_run_event(struct ssif_bmc_test_ctx *test_ctx,
+					   enum i2c_slave_event event, u8 value)
+{
+	return ssif_bmc_test_run_event_val(test_ctx, event, &value);
+}
+
+static void ssif_bmc_test_singlepart_req(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+
+	ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+				GET_8BIT_ADDR(test_ctx->client.addr));
+	ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+				SSIF_IPMI_SINGLEPART_WRITE);
+	ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 2);
+
+	ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0xaa);
+
+	ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0x55);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), -EBUSY);
+
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_READY);
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->busy);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->aborting);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.len, 2);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.payload[0], 0xaa);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.payload[1], 0x55);
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->response_timer_inited);
+}
+
+static void ssif_bmc_test_restart_write_without_stop(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 2), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0xde), 0);
+
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_REQ_RECVING);
+
+	/* Write transaction, without stop, and new request coming */
+	ssif_bmc_test_singlepart_req(test);
+}
+
+
+static void ssif_bmc_test_restart_after_invalid_command(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0xff), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 1), 0);
+
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_ABORTING);
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->aborting);
+
+	/* After An Invalid Command, expect could handle new request */
+	ssif_bmc_test_singlepart_req(test);
+}
+
+static void ssif_bmc_test_singlepart_read_response_completion(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+	u8 value;
+
+	ssif_bmc->state = SSIF_SMBUS_CMD;
+	ssif_bmc->part_buf.smbus_cmd = SSIF_IPMI_SINGLEPART_READ;
+	ssif_bmc->response.len = 2;
+	ssif_bmc->response.payload[0] = 0x11;
+	ssif_bmc->response.payload[1] = 0x22;
+	ssif_bmc->response_in_progress = true;
+	ssif_bmc->is_singlepart_read = true;
+	ssif_bmc->pec_support = true;
+
+	value = 0;
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_REQUESTED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, 2);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_RES_SENDING);
+
+	value = 0;
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_PROCESSED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, 0x11);
+
+	value = 0;
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_PROCESSED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, 0x22);
+
+	value = 0;
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_PROCESSED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, ssif_bmc->part_buf.pec);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_READY);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->response_in_progress);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->response.len, 0);
+}
+
+static void ssif_bmc_test_stop_during_start_discards_partial_request(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_START);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_READY);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->msg_idx, 0);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 1), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0x77), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), -EBUSY);
+
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.len, 1);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.payload[0], 0x77);
+}
+
+static void ssif_bmc_test_read_interrupts_partial_write(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+	u8 value = 0xff;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 2), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0xab), 0);
+
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_REQ_RECVING);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_REQUESTED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_ABORTING);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_READY);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.len, 0);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 1), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0xcd), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), -EBUSY);
+
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.len, 1);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.payload[0], 0xcd);
+}
+
+static void ssif_bmc_test_write_interrupts_response_send(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+	u8 value = 0;
+
+	ssif_bmc->state = SSIF_SMBUS_CMD;
+	ssif_bmc->part_buf.smbus_cmd = SSIF_IPMI_SINGLEPART_READ;
+	ssif_bmc->response.len = 1;
+	ssif_bmc->response.payload[0] = 0x66;
+	ssif_bmc->response_in_progress = true;
+	ssif_bmc->is_singlepart_read = true;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_REQUESTED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_RES_SENDING);
+
+	/* READ_REQUESTED transaction */
+	ssif_bmc_test_singlepart_req(test);
+}
+
+static void ssif_bmc_test_write_interrupts_response_sending(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+	u8 value = 0;
+
+	ssif_bmc->state = SSIF_SMBUS_CMD;
+	ssif_bmc->part_buf.smbus_cmd = SSIF_IPMI_SINGLEPART_READ;
+	ssif_bmc->response.len = 1;
+	ssif_bmc->response.payload[0] = 0x66;
+	ssif_bmc->response_in_progress = true;
+	ssif_bmc->is_singlepart_read = true;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_REQUESTED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->state, SSIF_RES_SENDING);
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event_val(test_ctx, I2C_SLAVE_READ_PROCESSED,
+						    &value), 0);
+	KUNIT_EXPECT_EQ(test, value, 0x66);
+
+	/* READ_REQUESTED transaction */
+	ssif_bmc_test_singlepart_req(test);
+}
+
+static void ssif_bmc_test_timeout_interrupt_allows_retry(struct kunit *test)
+{
+	struct ssif_bmc_test_ctx *test_ctx = test->priv;
+	struct ssif_bmc_ctx *ssif_bmc = &test_ctx->ssif_bmc;
+
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 1), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0x21), 0);
+	KUNIT_ASSERT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), -EBUSY);
+
+	KUNIT_ASSERT_TRUE(test, timer_pending(&ssif_bmc->response_timer));
+	timer_delete_sync(&ssif_bmc->response_timer);
+	response_timeout(&ssif_bmc->response_timer);
+
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->busy);
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->aborting);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->response_timer_inited);
+
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_REQUESTED,
+						GET_8BIT_ADDR(test_ctx->client.addr)), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED,
+						SSIF_IPMI_SINGLEPART_WRITE), 0);
+	KUNIT_EXPECT_FALSE(test, ssif_bmc->aborting);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 1), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_WRITE_RECEIVED, 0x22), 0);
+	KUNIT_EXPECT_EQ(test,
+			ssif_bmc_test_run_event(test_ctx, I2C_SLAVE_STOP, 0), -EBUSY);
+
+	KUNIT_EXPECT_TRUE(test, ssif_bmc->request_available);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.len, 1);
+	KUNIT_EXPECT_EQ(test, ssif_bmc->request.payload[0], 0x22);
+}
+
+static struct kunit_case ssif_bmc_test_cases[] = {
+	KUNIT_CASE(ssif_bmc_test_singlepart_req),
+	KUNIT_CASE(ssif_bmc_test_restart_write_without_stop),
+	KUNIT_CASE(ssif_bmc_test_restart_after_invalid_command),
+	KUNIT_CASE(ssif_bmc_test_singlepart_read_response_completion),
+	KUNIT_CASE(ssif_bmc_test_stop_during_start_discards_partial_request),
+	KUNIT_CASE(ssif_bmc_test_read_interrupts_partial_write),
+	KUNIT_CASE(ssif_bmc_test_write_interrupts_response_send),
+	KUNIT_CASE(ssif_bmc_test_write_interrupts_response_sending),
+	KUNIT_CASE(ssif_bmc_test_timeout_interrupt_allows_retry),
+	{}
+};
+
+static struct kunit_suite ssif_bmc_test_suite = {
+	.name = "ssif_bmc_test",
+	.init = ssif_bmc_test_init,
+	.exit = ssif_bmc_test_exit,
+	.test_cases = ssif_bmc_test_cases,
+};
+
+kunit_test_suite(ssif_bmc_test_suite);
+#endif
+
 module_i2c_driver(ssif_bmc_driver);
 
 MODULE_AUTHOR("Quan Nguyen <quan@os.amperecomputing.com>");
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c
index da930c7..2c9b12b 100644
--- a/drivers/char/nsc_gpio.c
+++ b/drivers/char/nsc_gpio.c
@@ -121,20 +121,6 @@ EXPORT_SYMBOL(nsc_gpio_write);
 EXPORT_SYMBOL(nsc_gpio_read);
 EXPORT_SYMBOL(nsc_gpio_dump);
 
-static int __init nsc_gpio_init(void)
-{
-	printk(KERN_DEBUG NAME " initializing\n");
-	return 0;
-}
-
-static void __exit nsc_gpio_cleanup(void)
-{
-	printk(KERN_DEBUG NAME " cleanup\n");
-}
-
-module_init(nsc_gpio_init);
-module_exit(nsc_gpio_cleanup);
-
 MODULE_AUTHOR("Jim Cromie <jim.cromie@gmail.com>");
 MODULE_DESCRIPTION("NatSemi GPIO Common Methods");
 MODULE_LICENSE("GPL");
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 677bb5a..ccda997 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1115,15 +1115,17 @@ static int sonypi_disable(void)
 }
 
 #ifdef CONFIG_ACPI
-static int sonypi_acpi_add(struct acpi_device *device)
+static int sonypi_acpi_probe(struct platform_device *pdev)
 {
+	struct acpi_device *device = ACPI_COMPANION(&pdev->dev);
+
 	sonypi_acpi_device = device;
 	strcpy(acpi_device_name(device), "Sony laptop hotkeys");
 	strcpy(acpi_device_class(device), "sony/hotkey");
 	return 0;
 }
 
-static void sonypi_acpi_remove(struct acpi_device *device)
+static void sonypi_acpi_remove(struct platform_device *pdev)
 {
 	sonypi_acpi_device = NULL;
 }
@@ -1133,13 +1135,12 @@ static const struct acpi_device_id sonypi_device_ids[] = {
 	{"", 0},
 };
 
-static struct acpi_driver sonypi_acpi_driver = {
-	.name           = "sonypi",
-	.class          = "hkey",
-	.ids            = sonypi_device_ids,
-	.ops            = {
-		           .add = sonypi_acpi_add,
-			   .remove = sonypi_acpi_remove,
+static struct platform_driver sonypi_acpi_driver = {
+	.probe = sonypi_acpi_probe,
+	.remove = sonypi_acpi_remove,
+	.driver = {
+		.name = "sonypi_acpi",
+		.acpi_match_table = sonypi_device_ids,
 	},
 };
 #endif
@@ -1518,8 +1519,8 @@ static int __init sonypi_init(void)
 		goto err_free_device;
 
 #ifdef CONFIG_ACPI
-	if (acpi_bus_register_driver(&sonypi_acpi_driver) >= 0)
-		acpi_driver_registered = 1;
+	error = platform_driver_register(&sonypi_acpi_driver);
+	acpi_driver_registered = !error;
 #endif
 
 	return 0;
@@ -1535,7 +1536,7 @@ static void __exit sonypi_exit(void)
 {
 #ifdef CONFIG_ACPI
 	if (acpi_driver_registered)
-		acpi_bus_unregister_driver(&sonypi_acpi_driver);
+		platform_driver_unregister(&sonypi_acpi_driver);
 #endif
 	platform_device_unregister(sonypi_platform_device);
 	platform_driver_unregister(&sonypi_driver);
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 240e9db..b2efbe9 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -218,13 +218,13 @@
 	  If you say yes here you get support for the CS2000 clock multiplier.
 
 config COMMON_CLK_EN7523
-	bool "Clock driver for Airoha EN7523 SoC system clocks"
+	bool "Clock driver for Airoha/EcoNet SoC system clocks"
 	depends on OF
-	depends on ARCH_AIROHA || COMPILE_TEST
+	depends on ARCH_AIROHA || ECONET || COMPILE_TEST
 	default ARCH_AIROHA
 	help
 	  This driver provides the fixed clocks and gates present on Airoha
-	  ARM silicon.
+	  and EcoNet silicon.
 
 config COMMON_CLK_EP93XX
 	tristate "Clock driver for Cirrus Logic ep93xx SoC"
@@ -255,7 +255,7 @@
 
 config COMMON_CLK_FSL_SAI
 	bool "Clock driver for BCLK of Freescale SAI cores"
-	depends on ARCH_LAYERSCAPE || COMPILE_TEST
+	depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST
 	help
 	  This driver supports the Freescale SAI (Synchronous Audio Interface)
 	  to be used as a generic clock output. Some SoCs have restrictions
@@ -502,8 +502,8 @@
 source "drivers/clk/actions/Kconfig"
 source "drivers/clk/analogbits/Kconfig"
 source "drivers/clk/aspeed/Kconfig"
-source "drivers/clk/baikal-t1/Kconfig"
 source "drivers/clk/bcm/Kconfig"
+source "drivers/clk/eswin/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
 source "drivers/clk/imx/Kconfig"
@@ -531,6 +531,7 @@
 source "drivers/clk/sunxi/Kconfig"
 source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
+source "drivers/clk/tenstorrent/Kconfig"
 source "drivers/clk/thead/Kconfig"
 source "drivers/clk/stm32/Kconfig"
 source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7bce39..a3e2862 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -116,10 +116,10 @@
 obj-$(CONFIG_COMMON_CLK_AT91)		+= at91/
 obj-$(CONFIG_ARCH_ARTPEC)		+= axis/
 obj-$(CONFIG_ARC_PLAT_AXS10X)		+= axs10x/
-obj-$(CONFIG_CLK_BAIKAL_T1)		+= baikal-t1/
 obj-y					+= bcm/
 obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
+obj-$(CONFIG_COMMON_CLK_ESWIN)		+= eswin/
 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
 obj-y					+= imgtec/
 obj-y					+= imx/
@@ -155,6 +155,7 @@
 obj-$(CONFIG_ARCH_SUNXI)		+= sunxi/
 obj-y					+= sunxi-ng/
 obj-$(CONFIG_ARCH_TEGRA)		+= tegra/
+obj-y					+= tenstorrent/
 obj-$(CONFIG_ARCH_THEAD)		+= thead/
 obj-y					+= ti/
 obj-$(CONFIG_CLK_UNIPHIER)		+= uniphier/
diff --git a/drivers/clk/baikal-t1/Kconfig b/drivers/clk/baikal-t1/Kconfig
deleted file mode 100644
index f0b1868..0000000
--- a/drivers/clk/baikal-t1/Kconfig
+++ /dev/null
@@ -1,52 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-config CLK_BAIKAL_T1
-	bool "Baikal-T1 Clocks Control Unit interface"
-	depends on (MIPS_BAIKAL_T1 && OF) || COMPILE_TEST
-	default MIPS_BAIKAL_T1
-	help
-	  Clocks Control Unit is the core of Baikal-T1 SoC System Controller
-	  responsible for the chip subsystems clocking and resetting. It
-	  consists of multiple global clock domains, which can be reset by
-	  means of the CCU control registers. These domains and devices placed
-	  in them are fed with clocks generated by a hierarchy of PLLs,
-	  configurable and fixed clock dividers. Enable this option to be able
-	  to select Baikal-T1 CCU PLLs and Dividers drivers.
-
-if CLK_BAIKAL_T1
-
-config CLK_BT1_CCU_PLL
-	bool "Baikal-T1 CCU PLLs support"
-	select MFD_SYSCON
-	default MIPS_BAIKAL_T1
-	help
-	  Enable this to support the PLLs embedded into the Baikal-T1 SoC
-	  System Controller. These are five PLLs placed at the root of the
-	  clocks hierarchy, right after an external reference oscillator
-	  (normally of 25MHz). They are used to generate high frequency
-	  signals, which are either directly wired to the consumers (like
-	  CPUs, DDR, etc.) or passed over the clock dividers to be only
-	  then used as an individual reference clock of a target device.
-
-config CLK_BT1_CCU_DIV
-	bool "Baikal-T1 CCU Dividers support"
-	select MFD_SYSCON
-	default MIPS_BAIKAL_T1
-	help
-	  Enable this to support the CCU dividers used to distribute clocks
-	  between AXI-bus and system devices coming from CCU PLLs of Baikal-T1
-	  SoC. CCU dividers can be either configurable or with fixed divider,
-	  either gateable or ungateable. Some of the CCU dividers can be as well
-	  used to reset the domains they're supplying clock to.
-
-config CLK_BT1_CCU_RST
-	bool "Baikal-T1 CCU Resets support"
-	select RESET_CONTROLLER
-	select MFD_SYSCON
-	default MIPS_BAIKAL_T1
-	help
-	  Enable this to support the CCU reset blocks responsible for the
-	  AXI-bus and some subsystems reset. These are mainly the
-	  self-deasserted reset controls but there are several lines which
-	  can be directly asserted/de-asserted (PCIe and DDR sub-domains).
-
-endif
diff --git a/drivers/clk/baikal-t1/Makefile b/drivers/clk/baikal-t1/Makefile
deleted file mode 100644
index 9c3637d..0000000
--- a/drivers/clk/baikal-t1/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_CLK_BT1_CCU_PLL) += ccu-pll.o clk-ccu-pll.o
-obj-$(CONFIG_CLK_BT1_CCU_DIV) += ccu-div.o clk-ccu-div.o
-obj-$(CONFIG_CLK_BT1_CCU_RST) += ccu-rst.o
diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c
deleted file mode 100644
index cc48e58..0000000
--- a/drivers/clk/baikal-t1/ccu-div.c
+++ /dev/null
@@ -1,653 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *   Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
- *
- * Baikal-T1 CCU Dividers interface driver
- */
-
-#define pr_fmt(fmt) "bt1-ccu-div: " fmt
-
-#include <linux/kernel.h>
-#include <linux/printk.h>
-#include <linux/bits.h>
-#include <linux/bitfield.h>
-#include <linux/slab.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/spinlock.h>
-#include <linux/regmap.h>
-#include <linux/delay.h>
-#include <linux/time64.h>
-#include <linux/debugfs.h>
-
-#include "ccu-div.h"
-
-#define CCU_DIV_CTL			0x00
-#define CCU_DIV_CTL_EN			BIT(0)
-#define CCU_DIV_CTL_RST			BIT(1)
-#define CCU_DIV_CTL_SET_CLKDIV		BIT(2)
-#define CCU_DIV_CTL_CLKDIV_FLD		4
-#define CCU_DIV_CTL_CLKDIV_MASK(_width) \
-	GENMASK((_width) + CCU_DIV_CTL_CLKDIV_FLD - 1, CCU_DIV_CTL_CLKDIV_FLD)
-#define CCU_DIV_CTL_LOCK_SHIFTED	BIT(27)
-#define CCU_DIV_CTL_GATE_REF_BUF	BIT(28)
-#define CCU_DIV_CTL_LOCK_NORMAL		BIT(31)
-
-#define CCU_DIV_LOCK_CHECK_RETRIES	50
-
-#define CCU_DIV_CLKDIV_MIN		0
-#define CCU_DIV_CLKDIV_MAX(_mask) \
-	((_mask) >> CCU_DIV_CTL_CLKDIV_FLD)
-
-/*
- * Use the next two methods until there are generic field setter and
- * getter available with non-constant mask support.
- */
-static inline u32 ccu_div_get(u32 mask, u32 val)
-{
-	return (val & mask) >> CCU_DIV_CTL_CLKDIV_FLD;
-}
-
-static inline u32 ccu_div_prep(u32 mask, u32 val)
-{
-	return (val << CCU_DIV_CTL_CLKDIV_FLD) & mask;
-}
-
-static inline unsigned long ccu_div_lock_delay_ns(unsigned long ref_clk,
-						  unsigned long div)
-{
-	u64 ns = 4ULL * (div ?: 1) * NSEC_PER_SEC;
-
-	do_div(ns, ref_clk);
-
-	return ns;
-}
-
-static inline unsigned long ccu_div_calc_freq(unsigned long ref_clk,
-					      unsigned long div)
-{
-	return ref_clk / (div ?: 1);
-}
-
-static int ccu_div_var_update_clkdiv(struct ccu_div *div,
-				     unsigned long parent_rate,
-				     unsigned long divider)
-{
-	unsigned long nd;
-	u32 val = 0;
-	u32 lock;
-	int count;
-
-	nd = ccu_div_lock_delay_ns(parent_rate, divider);
-
-	if (div->features & CCU_DIV_LOCK_SHIFTED)
-		lock = CCU_DIV_CTL_LOCK_SHIFTED;
-	else
-		lock = CCU_DIV_CTL_LOCK_NORMAL;
-
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   CCU_DIV_CTL_SET_CLKDIV, CCU_DIV_CTL_SET_CLKDIV);
-
-	/*
-	 * Until there is nsec-version of readl_poll_timeout() is available
-	 * we have to implement the next polling loop.
-	 */
-	count = CCU_DIV_LOCK_CHECK_RETRIES;
-	do {
-		ndelay(nd);
-		regmap_read(div->sys_regs, div->reg_ctl, &val);
-		if (val & lock)
-			return 0;
-	} while (--count);
-
-	return -ETIMEDOUT;
-}
-
-static int ccu_div_var_enable(struct clk_hw *hw)
-{
-	struct clk_hw *parent_hw = clk_hw_get_parent(hw);
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags;
-	u32 val = 0;
-	int ret;
-
-	if (!parent_hw) {
-		pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
-		return -EINVAL;
-	}
-
-	regmap_read(div->sys_regs, div->reg_ctl, &val);
-	if (val & CCU_DIV_CTL_EN)
-		return 0;
-
-	spin_lock_irqsave(&div->lock, flags);
-	ret = ccu_div_var_update_clkdiv(div, clk_hw_get_rate(parent_hw),
-					ccu_div_get(div->mask, val));
-	if (!ret)
-		regmap_update_bits(div->sys_regs, div->reg_ctl,
-				   CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
-	spin_unlock_irqrestore(&div->lock, flags);
-	if (ret)
-		pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
-
-	return ret;
-}
-
-static int ccu_div_gate_enable(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags;
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   CCU_DIV_CTL_EN, CCU_DIV_CTL_EN);
-	spin_unlock_irqrestore(&div->lock, flags);
-
-	return 0;
-}
-
-static void ccu_div_gate_disable(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags;
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl, CCU_DIV_CTL_EN, 0);
-	spin_unlock_irqrestore(&div->lock, flags);
-}
-
-static int ccu_div_gate_is_enabled(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	u32 val = 0;
-
-	regmap_read(div->sys_regs, div->reg_ctl, &val);
-
-	return !!(val & CCU_DIV_CTL_EN);
-}
-
-static int ccu_div_buf_enable(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags;
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   CCU_DIV_CTL_GATE_REF_BUF, 0);
-	spin_unlock_irqrestore(&div->lock, flags);
-
-	return 0;
-}
-
-static void ccu_div_buf_disable(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags;
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   CCU_DIV_CTL_GATE_REF_BUF, CCU_DIV_CTL_GATE_REF_BUF);
-	spin_unlock_irqrestore(&div->lock, flags);
-}
-
-static int ccu_div_buf_is_enabled(struct clk_hw *hw)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	u32 val = 0;
-
-	regmap_read(div->sys_regs, div->reg_ctl, &val);
-
-	return !(val & CCU_DIV_CTL_GATE_REF_BUF);
-}
-
-static unsigned long ccu_div_var_recalc_rate(struct clk_hw *hw,
-					     unsigned long parent_rate)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long divider;
-	u32 val = 0;
-
-	regmap_read(div->sys_regs, div->reg_ctl, &val);
-	divider = ccu_div_get(div->mask, val);
-
-	return ccu_div_calc_freq(parent_rate, divider);
-}
-
-static inline unsigned long ccu_div_var_calc_divider(unsigned long rate,
-						     unsigned long parent_rate,
-						     unsigned int mask)
-{
-	unsigned long divider;
-
-	divider = parent_rate / rate;
-	return clamp_t(unsigned long, divider, CCU_DIV_CLKDIV_MIN,
-		       CCU_DIV_CLKDIV_MAX(mask));
-}
-
-static int ccu_div_var_determine_rate(struct clk_hw *hw,
-				      struct clk_rate_request *req)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long divider;
-
-	divider = ccu_div_var_calc_divider(req->rate, req->best_parent_rate,
-					   div->mask);
-
-	req->rate = ccu_div_calc_freq(req->best_parent_rate, divider);
-
-	return 0;
-}
-
-/*
- * This method is used for the clock divider blocks, which support the
- * on-the-fly rate change. So due to lacking the EN bit functionality
- * they can't be gated before the rate adjustment.
- */
-static int ccu_div_var_set_rate_slow(struct clk_hw *hw, unsigned long rate,
-				     unsigned long parent_rate)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags, divider;
-	u32 val;
-	int ret;
-
-	divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
-	if (divider == 1 && div->features & CCU_DIV_SKIP_ONE) {
-		divider = 0;
-	} else if (div->features & CCU_DIV_SKIP_ONE_TO_THREE) {
-		if (divider == 1 || divider == 2)
-			divider = 0;
-		else if (divider == 3)
-			divider = 4;
-	}
-
-	val = ccu_div_prep(div->mask, divider);
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, val);
-	ret = ccu_div_var_update_clkdiv(div, parent_rate, divider);
-	spin_unlock_irqrestore(&div->lock, flags);
-	if (ret)
-		pr_err("Divider '%s' lock timed out\n", clk_hw_get_name(hw));
-
-	return ret;
-}
-
-/*
- * This method is used for the clock divider blocks, which don't support
- * the on-the-fly rate change.
- */
-static int ccu_div_var_set_rate_fast(struct clk_hw *hw, unsigned long rate,
-				     unsigned long parent_rate)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	unsigned long flags, divider;
-	u32 val;
-
-	divider = ccu_div_var_calc_divider(rate, parent_rate, div->mask);
-	val = ccu_div_prep(div->mask, divider);
-
-	/*
-	 * Also disable the clock divider block if it was enabled by default
-	 * or by the bootloader.
-	 */
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   div->mask | CCU_DIV_CTL_EN, val);
-	spin_unlock_irqrestore(&div->lock, flags);
-
-	return 0;
-}
-
-static unsigned long ccu_div_fixed_recalc_rate(struct clk_hw *hw,
-					       unsigned long parent_rate)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-
-	return ccu_div_calc_freq(parent_rate, div->divider);
-}
-
-static int ccu_div_fixed_determine_rate(struct clk_hw *hw,
-					struct clk_rate_request *req)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-
-	req->rate = ccu_div_calc_freq(req->best_parent_rate, div->divider);
-
-	return 0;
-}
-
-static int ccu_div_fixed_set_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long parent_rate)
-{
-	return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-struct ccu_div_dbgfs_bit {
-	struct ccu_div *div;
-	const char *name;
-	u32 mask;
-};
-
-#define CCU_DIV_DBGFS_BIT_ATTR(_name, _mask) {	\
-		.name = _name,			\
-		.mask = _mask			\
-	}
-
-static const struct ccu_div_dbgfs_bit ccu_div_bits[] = {
-	CCU_DIV_DBGFS_BIT_ATTR("div_en", CCU_DIV_CTL_EN),
-	CCU_DIV_DBGFS_BIT_ATTR("div_rst", CCU_DIV_CTL_RST),
-	CCU_DIV_DBGFS_BIT_ATTR("div_bypass", CCU_DIV_CTL_SET_CLKDIV),
-	CCU_DIV_DBGFS_BIT_ATTR("div_buf", CCU_DIV_CTL_GATE_REF_BUF),
-	CCU_DIV_DBGFS_BIT_ATTR("div_lock", CCU_DIV_CTL_LOCK_NORMAL)
-};
-
-#define CCU_DIV_DBGFS_BIT_NUM	ARRAY_SIZE(ccu_div_bits)
-
-/*
- * It can be dangerous to change the Divider settings behind clock framework
- * back, therefore we don't provide any kernel config based compile time option
- * for this feature to enable.
- */
-#undef CCU_DIV_ALLOW_WRITE_DEBUGFS
-#ifdef CCU_DIV_ALLOW_WRITE_DEBUGFS
-
-static int ccu_div_dbgfs_bit_set(void *priv, u64 val)
-{
-	const struct ccu_div_dbgfs_bit *bit = priv;
-	struct ccu_div *div = bit->div;
-	unsigned long flags;
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl,
-			   bit->mask, val ? bit->mask : 0);
-	spin_unlock_irqrestore(&div->lock, flags);
-
-	return 0;
-}
-
-static int ccu_div_dbgfs_var_clkdiv_set(void *priv, u64 val)
-{
-	struct ccu_div *div = priv;
-	unsigned long flags;
-	u32 data;
-
-	val = clamp_t(u64, val, CCU_DIV_CLKDIV_MIN,
-		      CCU_DIV_CLKDIV_MAX(div->mask));
-	data = ccu_div_prep(div->mask, val);
-
-	spin_lock_irqsave(&div->lock, flags);
-	regmap_update_bits(div->sys_regs, div->reg_ctl, div->mask, data);
-	spin_unlock_irqrestore(&div->lock, flags);
-
-	return 0;
-}
-
-#define ccu_div_dbgfs_mode		0644
-
-#else /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
-
-#define ccu_div_dbgfs_bit_set		NULL
-#define ccu_div_dbgfs_var_clkdiv_set	NULL
-#define ccu_div_dbgfs_mode		0444
-
-#endif /* !CCU_DIV_ALLOW_WRITE_DEBUGFS */
-
-static int ccu_div_dbgfs_bit_get(void *priv, u64 *val)
-{
-	const struct ccu_div_dbgfs_bit *bit = priv;
-	struct ccu_div *div = bit->div;
-	u32 data = 0;
-
-	regmap_read(div->sys_regs, div->reg_ctl, &data);
-	*val = !!(data & bit->mask);
-
-	return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_bit_fops,
-	ccu_div_dbgfs_bit_get, ccu_div_dbgfs_bit_set, "%llu\n");
-
-static int ccu_div_dbgfs_var_clkdiv_get(void *priv, u64 *val)
-{
-	struct ccu_div *div = priv;
-	u32 data = 0;
-
-	regmap_read(div->sys_regs, div->reg_ctl, &data);
-	*val = ccu_div_get(div->mask, data);
-
-	return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_var_clkdiv_fops,
-	ccu_div_dbgfs_var_clkdiv_get, ccu_div_dbgfs_var_clkdiv_set, "%llu\n");
-
-static int ccu_div_dbgfs_fixed_clkdiv_get(void *priv, u64 *val)
-{
-	struct ccu_div *div = priv;
-
-	*val = div->divider;
-
-	return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(ccu_div_dbgfs_fixed_clkdiv_fops,
-	ccu_div_dbgfs_fixed_clkdiv_get, NULL, "%llu\n");
-
-static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	struct ccu_div_dbgfs_bit *bits;
-	int didx, bidx, num = 2;
-	const char *name;
-
-	num += !!(div->flags & CLK_SET_RATE_GATE) +
-		!!(div->features & CCU_DIV_RESET_DOMAIN);
-
-	bits = kzalloc_objs(*bits, num);
-	if (!bits)
-		return;
-
-	for (didx = 0, bidx = 0; bidx < CCU_DIV_DBGFS_BIT_NUM; ++bidx) {
-		name = ccu_div_bits[bidx].name;
-		if (!(div->flags & CLK_SET_RATE_GATE) &&
-		    !strcmp("div_en", name)) {
-			continue;
-		}
-
-		if (!(div->features & CCU_DIV_RESET_DOMAIN) &&
-		    !strcmp("div_rst", name)) {
-			continue;
-		}
-
-		if (!strcmp("div_buf", name))
-			continue;
-
-		bits[didx] = ccu_div_bits[bidx];
-		bits[didx].div = div;
-
-		if (div->features & CCU_DIV_LOCK_SHIFTED &&
-		    !strcmp("div_lock", name)) {
-			bits[didx].mask = CCU_DIV_CTL_LOCK_SHIFTED;
-		}
-
-		debugfs_create_file_unsafe(bits[didx].name, ccu_div_dbgfs_mode,
-					   dentry, &bits[didx],
-					   &ccu_div_dbgfs_bit_fops);
-		++didx;
-	}
-
-	debugfs_create_file_unsafe("div_clkdiv", ccu_div_dbgfs_mode, dentry,
-				   div, &ccu_div_dbgfs_var_clkdiv_fops);
-}
-
-static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	struct ccu_div_dbgfs_bit *bit;
-
-	bit = kmalloc_obj(*bit);
-	if (!bit)
-		return;
-
-	*bit = ccu_div_bits[0];
-	bit->div = div;
-	debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
-				   &ccu_div_dbgfs_bit_fops);
-
-	debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
-				   &ccu_div_dbgfs_fixed_clkdiv_fops);
-}
-
-static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-	struct ccu_div_dbgfs_bit *bit;
-
-	bit = kmalloc_obj(*bit);
-	if (!bit)
-		return;
-
-	*bit = ccu_div_bits[3];
-	bit->div = div;
-	debugfs_create_file_unsafe(bit->name, ccu_div_dbgfs_mode, dentry, bit,
-				   &ccu_div_dbgfs_bit_fops);
-}
-
-static void ccu_div_fixed_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
-	struct ccu_div *div = to_ccu_div(hw);
-
-	debugfs_create_file_unsafe("div_clkdiv", 0400, dentry, div,
-				   &ccu_div_dbgfs_fixed_clkdiv_fops);
-}
-
-#else /* !CONFIG_DEBUG_FS */
-
-#define ccu_div_var_debug_init NULL
-#define ccu_div_gate_debug_init NULL
-#define ccu_div_buf_debug_init NULL
-#define ccu_div_fixed_debug_init NULL
-
-#endif /* !CONFIG_DEBUG_FS */
-
-static const struct clk_ops ccu_div_var_gate_to_set_ops = {
-	.enable = ccu_div_var_enable,
-	.disable = ccu_div_gate_disable,
-	.is_enabled = ccu_div_gate_is_enabled,
-	.recalc_rate = ccu_div_var_recalc_rate,
-	.determine_rate = ccu_div_var_determine_rate,
-	.set_rate = ccu_div_var_set_rate_fast,
-	.debug_init = ccu_div_var_debug_init
-};
-
-static const struct clk_ops ccu_div_var_nogate_ops = {
-	.recalc_rate = ccu_div_var_recalc_rate,
-	.determine_rate = ccu_div_var_determine_rate,
-	.set_rate = ccu_div_var_set_rate_slow,
-	.debug_init = ccu_div_var_debug_init
-};
-
-static const struct clk_ops ccu_div_gate_ops = {
-	.enable = ccu_div_gate_enable,
-	.disable = ccu_div_gate_disable,
-	.is_enabled = ccu_div_gate_is_enabled,
-	.recalc_rate = ccu_div_fixed_recalc_rate,
-	.determine_rate = ccu_div_fixed_determine_rate,
-	.set_rate = ccu_div_fixed_set_rate,
-	.debug_init = ccu_div_gate_debug_init
-};
-
-static const struct clk_ops ccu_div_buf_ops = {
-	.enable = ccu_div_buf_enable,
-	.disable = ccu_div_buf_disable,
-	.is_enabled = ccu_div_buf_is_enabled,
-	.debug_init = ccu_div_buf_debug_init
-};
-
-static const struct clk_ops ccu_div_fixed_ops = {
-	.recalc_rate = ccu_div_fixed_recalc_rate,
-	.determine_rate = ccu_div_fixed_determine_rate,
-	.set_rate = ccu_div_fixed_set_rate,
-	.debug_init = ccu_div_fixed_debug_init
-};
-
-struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init)
-{
-	struct clk_parent_data parent_data = { };
-	struct clk_init_data hw_init = { };
-	struct ccu_div *div;
-	int ret;
-
-	if (!div_init)
-		return ERR_PTR(-EINVAL);
-
-	div = kzalloc_obj(*div);
-	if (!div)
-		return ERR_PTR(-ENOMEM);
-
-	/*
-	 * Note since Baikal-T1 System Controller registers are MMIO-backed
-	 * we won't check the regmap IO operations return status, because it
-	 * must be zero anyway.
-	 */
-	div->hw.init = &hw_init;
-	div->id = div_init->id;
-	div->reg_ctl = div_init->base + CCU_DIV_CTL;
-	div->sys_regs = div_init->sys_regs;
-	div->flags = div_init->flags;
-	div->features = div_init->features;
-	spin_lock_init(&div->lock);
-
-	hw_init.name = div_init->name;
-	hw_init.flags = div_init->flags;
-
-	if (div_init->type == CCU_DIV_VAR) {
-		if (hw_init.flags & CLK_SET_RATE_GATE)
-			hw_init.ops = &ccu_div_var_gate_to_set_ops;
-		else
-			hw_init.ops = &ccu_div_var_nogate_ops;
-		div->mask = CCU_DIV_CTL_CLKDIV_MASK(div_init->width);
-	} else if (div_init->type == CCU_DIV_GATE) {
-		hw_init.ops = &ccu_div_gate_ops;
-		div->divider = div_init->divider;
-	} else if (div_init->type == CCU_DIV_BUF) {
-		hw_init.ops = &ccu_div_buf_ops;
-	} else if (div_init->type == CCU_DIV_FIXED) {
-		hw_init.ops = &ccu_div_fixed_ops;
-		div->divider = div_init->divider;
-	} else {
-		ret = -EINVAL;
-		goto err_free_div;
-	}
-
-	if (!div_init->parent_name) {
-		ret = -EINVAL;
-		goto err_free_div;
-	}
-	parent_data.fw_name = div_init->parent_name;
-	parent_data.name = div_init->parent_name;
-	hw_init.parent_data = &parent_data;
-	hw_init.num_parents = 1;
-
-	ret = of_clk_hw_register(div_init->np, &div->hw);
-	if (ret)
-		goto err_free_div;
-
-	return div;
-
-err_free_div:
-	kfree(div);
-
-	return ERR_PTR(ret);
-}
-
-void ccu_div_hw_unregister(struct ccu_div *div)
-{
-	clk_hw_unregister(&div->hw);
-
-	kfree(div);
-}
diff --git a/drivers/clk/baikal-t1/ccu-div.h b/drivers/clk/baikal-t1/ccu-div.h
deleted file mode 100644
index 76d8ee4..0000000
--- a/drivers/clk/baikal-t1/ccu-div.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Baikal-T1 CCU Dividers interface driver
- */
-#ifndef __CLK_BT1_CCU_DIV_H__
-#define __CLK_BT1_CCU_DIV_H__
-
-#include <linux/clk-provider.h>
-#include <linux/spinlock.h>
-#include <linux/regmap.h>
-#include <linux/bits.h>
-#include <linux/of.h>
-
-/*
- * CCU Divider private clock IDs
- * @CCU_SYS_SATA_CLK: CCU SATA internal clock
- * @CCU_SYS_XGMAC_CLK: CCU XGMAC internal clock
- */
-#define CCU_SYS_SATA_CLK		-1
-#define CCU_SYS_XGMAC_CLK		-2
-
-/*
- * CCU Divider private flags
- * @CCU_DIV_BASIC: Basic divider clock required by the kernel as early as
- *		   possible.
- * @CCU_DIV_SKIP_ONE: Due to some reason divider can't be set to 1.
- *		      It can be 0 though, which is functionally the same.
- * @CCU_DIV_SKIP_ONE_TO_THREE: For some reason divider can't be within [1,3].
- *			       It can be either 0 or greater than 3.
- * @CCU_DIV_LOCK_SHIFTED: Find lock-bit at non-standard position.
- * @CCU_DIV_RESET_DOMAIN: There is a clock domain reset handle.
- */
-#define CCU_DIV_BASIC			BIT(0)
-#define CCU_DIV_SKIP_ONE		BIT(1)
-#define CCU_DIV_SKIP_ONE_TO_THREE	BIT(2)
-#define CCU_DIV_LOCK_SHIFTED		BIT(3)
-#define CCU_DIV_RESET_DOMAIN		BIT(4)
-
-/*
- * enum ccu_div_type - CCU Divider types
- * @CCU_DIV_VAR: Clocks gate with variable divider.
- * @CCU_DIV_GATE: Clocks gate with fixed divider.
- * @CCU_DIV_BUF: Clock gate with no divider.
- * @CCU_DIV_FIXED: Ungateable clock with fixed divider.
- */
-enum ccu_div_type {
-	CCU_DIV_VAR,
-	CCU_DIV_GATE,
-	CCU_DIV_BUF,
-	CCU_DIV_FIXED
-};
-
-/*
- * struct ccu_div_init_data - CCU Divider initialization data
- * @id: Clocks private identifier.
- * @name: Clocks name.
- * @parent_name: Parent clocks name in a fw node.
- * @base: Divider register base address with respect to the sys_regs base.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @np: Pointer to the node describing the CCU Dividers.
- * @type: CCU divider type (variable, fixed with and without gate).
- * @width: Divider width if it's variable.
- * @divider: Divider fixed value.
- * @flags: CCU Divider clock flags.
- * @features: CCU Divider private features.
- */
-struct ccu_div_init_data {
-	unsigned int id;
-	const char *name;
-	const char *parent_name;
-	unsigned int base;
-	struct regmap *sys_regs;
-	struct device_node *np;
-	enum ccu_div_type type;
-	union {
-		unsigned int width;
-		unsigned int divider;
-	};
-	unsigned long flags;
-	unsigned long features;
-};
-
-/*
- * struct ccu_div - CCU Divider descriptor
- * @hw: clk_hw of the divider.
- * @id: Clock private identifier.
- * @reg_ctl: Divider control register base address.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @lock: Divider state change spin-lock.
- * @mask: Divider field mask.
- * @divider: Divider fixed value.
- * @flags: Divider clock flags.
- * @features: CCU Divider private features.
- */
-struct ccu_div {
-	struct clk_hw hw;
-	unsigned int id;
-	unsigned int reg_ctl;
-	struct regmap *sys_regs;
-	spinlock_t lock;
-	union {
-		u32 mask;
-		unsigned int divider;
-	};
-	unsigned long flags;
-	unsigned long features;
-};
-#define to_ccu_div(_hw) container_of(_hw, struct ccu_div, hw)
-
-static inline struct clk_hw *ccu_div_get_clk_hw(struct ccu_div *div)
-{
-	return div ? &div->hw : NULL;
-}
-
-struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *init);
-
-void ccu_div_hw_unregister(struct ccu_div *div);
-
-#endif /* __CLK_BT1_CCU_DIV_H__ */
diff --git a/drivers/clk/baikal-t1/ccu-pll.c b/drivers/clk/baikal-t1/ccu-pll.c
deleted file mode 100644
index da7fbeb..0000000
--- a/drivers/clk/baikal-t1/ccu-pll.c
+++ /dev/null
@@ -1,560 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *   Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
- *
- * Baikal-T1 CCU PLL interface driver
- */
-
-#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
-
-#include <linux/kernel.h>
-#include <linux/printk.h>
-#include <linux/limits.h>
-#include <linux/bits.h>
-#include <linux/bitfield.h>
-#include <linux/slab.h>
-#include <linux/clk-provider.h>
-#include <linux/of.h>
-#include <linux/spinlock.h>
-#include <linux/regmap.h>
-#include <linux/iopoll.h>
-#include <linux/time64.h>
-#include <linux/rational.h>
-#include <linux/debugfs.h>
-
-#include "ccu-pll.h"
-
-#define CCU_PLL_CTL			0x000
-#define CCU_PLL_CTL_EN			BIT(0)
-#define CCU_PLL_CTL_RST			BIT(1)
-#define CCU_PLL_CTL_CLKR_FLD		2
-#define CCU_PLL_CTL_CLKR_MASK		GENMASK(7, CCU_PLL_CTL_CLKR_FLD)
-#define CCU_PLL_CTL_CLKF_FLD		8
-#define CCU_PLL_CTL_CLKF_MASK		GENMASK(20, CCU_PLL_CTL_CLKF_FLD)
-#define CCU_PLL_CTL_CLKOD_FLD		21
-#define CCU_PLL_CTL_CLKOD_MASK		GENMASK(24, CCU_PLL_CTL_CLKOD_FLD)
-#define CCU_PLL_CTL_BYPASS		BIT(30)
-#define CCU_PLL_CTL_LOCK		BIT(31)
-#define CCU_PLL_CTL1			0x004
-#define CCU_PLL_CTL1_BWADJ_FLD		3
-#define CCU_PLL_CTL1_BWADJ_MASK		GENMASK(14, CCU_PLL_CTL1_BWADJ_FLD)
-
-#define CCU_PLL_LOCK_CHECK_RETRIES	50
-
-#define CCU_PLL_NR_MAX \
-	((CCU_PLL_CTL_CLKR_MASK >> CCU_PLL_CTL_CLKR_FLD) + 1)
-#define CCU_PLL_NF_MAX \
-	((CCU_PLL_CTL_CLKF_MASK >> (CCU_PLL_CTL_CLKF_FLD + 1)) + 1)
-#define CCU_PLL_OD_MAX \
-	((CCU_PLL_CTL_CLKOD_MASK >> CCU_PLL_CTL_CLKOD_FLD) + 1)
-#define CCU_PLL_NB_MAX \
-	((CCU_PLL_CTL1_BWADJ_MASK >> CCU_PLL_CTL1_BWADJ_FLD) + 1)
-#define CCU_PLL_FDIV_MIN		427000UL
-#define CCU_PLL_FDIV_MAX		3500000000UL
-#define CCU_PLL_FOUT_MIN		200000000UL
-#define CCU_PLL_FOUT_MAX		2500000000UL
-#define CCU_PLL_FVCO_MIN		700000000UL
-#define CCU_PLL_FVCO_MAX		3500000000UL
-#define CCU_PLL_CLKOD_FACTOR		2
-
-static inline unsigned long ccu_pll_lock_delay_us(unsigned long ref_clk,
-						  unsigned long nr)
-{
-	u64 us = 500ULL * nr * USEC_PER_SEC;
-
-	do_div(us, ref_clk);
-
-	return us;
-}
-
-static inline unsigned long ccu_pll_calc_freq(unsigned long ref_clk,
-					      unsigned long nr,
-					      unsigned long nf,
-					      unsigned long od)
-{
-	u64 tmp = ref_clk;
-
-	do_div(tmp, nr);
-	tmp *= nf;
-	do_div(tmp, od);
-
-	return tmp;
-}
-
-static int ccu_pll_reset(struct ccu_pll *pll, unsigned long ref_clk,
-			 unsigned long nr)
-{
-	unsigned long ud, ut;
-	u32 val;
-
-	ud = ccu_pll_lock_delay_us(ref_clk, nr);
-	ut = ud * CCU_PLL_LOCK_CHECK_RETRIES;
-
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl,
-			   CCU_PLL_CTL_RST, CCU_PLL_CTL_RST);
-
-	return regmap_read_poll_timeout_atomic(pll->sys_regs, pll->reg_ctl, val,
-					       val & CCU_PLL_CTL_LOCK, ud, ut);
-}
-
-static int ccu_pll_enable(struct clk_hw *hw)
-{
-	struct clk_hw *parent_hw = clk_hw_get_parent(hw);
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	unsigned long flags;
-	u32 val = 0;
-	int ret;
-
-	if (!parent_hw) {
-		pr_err("Can't enable '%s' with no parent", clk_hw_get_name(hw));
-		return -EINVAL;
-	}
-
-	regmap_read(pll->sys_regs, pll->reg_ctl, &val);
-	if (val & CCU_PLL_CTL_EN)
-		return 0;
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_write(pll->sys_regs, pll->reg_ctl, val | CCU_PLL_CTL_EN);
-	ret = ccu_pll_reset(pll, clk_hw_get_rate(parent_hw),
-			    FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1);
-	spin_unlock_irqrestore(&pll->lock, flags);
-	if (ret)
-		pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
-
-	return ret;
-}
-
-static void ccu_pll_disable(struct clk_hw *hw)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	unsigned long flags;
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl, CCU_PLL_CTL_EN, 0);
-	spin_unlock_irqrestore(&pll->lock, flags);
-}
-
-static int ccu_pll_is_enabled(struct clk_hw *hw)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	u32 val = 0;
-
-	regmap_read(pll->sys_regs, pll->reg_ctl, &val);
-
-	return !!(val & CCU_PLL_CTL_EN);
-}
-
-static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
-					 unsigned long parent_rate)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	unsigned long nr, nf, od;
-	u32 val = 0;
-
-	regmap_read(pll->sys_regs, pll->reg_ctl, &val);
-	nr = FIELD_GET(CCU_PLL_CTL_CLKR_MASK, val) + 1;
-	nf = FIELD_GET(CCU_PLL_CTL_CLKF_MASK, val) + 1;
-	od = FIELD_GET(CCU_PLL_CTL_CLKOD_MASK, val) + 1;
-
-	return ccu_pll_calc_freq(parent_rate, nr, nf, od);
-}
-
-static void ccu_pll_calc_factors(unsigned long rate, unsigned long parent_rate,
-				 unsigned long *nr, unsigned long *nf,
-				 unsigned long *od)
-{
-	unsigned long err, freq, min_err = ULONG_MAX;
-	unsigned long num, denom, n1, d1, nri;
-	unsigned long nr_max, nf_max, od_max;
-
-	/*
-	 * Make sure PLL is working with valid input signal (Fdiv). If
-	 * you want to speed the function up just reduce CCU_PLL_NR_MAX.
-	 * This will cause a worse approximation though.
-	 */
-	nri = (parent_rate / CCU_PLL_FDIV_MAX) + 1;
-	nr_max = min(parent_rate / CCU_PLL_FDIV_MIN, CCU_PLL_NR_MAX);
-
-	/*
-	 * Find a closest [nr;nf;od] vector taking into account the
-	 * limitations like: 1) 700MHz <= Fvco <= 3.5GHz, 2) PLL Od is
-	 * either 1 or even number within the acceptable range (alas 1s
-	 * is also excluded by the next loop).
-	 */
-	for (; nri <= nr_max; ++nri) {
-		/* Use Od factor to fulfill the limitation 2). */
-		num = CCU_PLL_CLKOD_FACTOR * rate;
-		denom = parent_rate / nri;
-
-		/*
-		 * Make sure Fvco is within the acceptable range to fulfill
-		 * the condition 1). Note due to the CCU_PLL_CLKOD_FACTOR value
-		 * the actual upper limit is also divided by that factor.
-		 * It's not big problem for us since practically there is no
-		 * need in clocks with that high frequency.
-		 */
-		nf_max = min(CCU_PLL_FVCO_MAX / denom, CCU_PLL_NF_MAX);
-		od_max = CCU_PLL_OD_MAX / CCU_PLL_CLKOD_FACTOR;
-
-		/*
-		 * Bypass the out-of-bound values, which can't be properly
-		 * handled by the rational fraction approximation algorithm.
-		 */
-		if (num / denom >= nf_max) {
-			n1 = nf_max;
-			d1 = 1;
-		} else if (denom / num >= od_max) {
-			n1 = 1;
-			d1 = od_max;
-		} else {
-			rational_best_approximation(num, denom, nf_max, od_max,
-						    &n1, &d1);
-		}
-
-		/* Select the best approximation of the target rate. */
-		freq = ccu_pll_calc_freq(parent_rate, nri, n1, d1);
-		err = abs((int64_t)freq - num);
-		if (err < min_err) {
-			min_err = err;
-			*nr = nri;
-			*nf = n1;
-			*od = CCU_PLL_CLKOD_FACTOR * d1;
-		}
-	}
-}
-
-static int ccu_pll_determine_rate(struct clk_hw *hw,
-				  struct clk_rate_request *req)
-{
-	unsigned long nr = 1, nf = 1, od = 1;
-
-	ccu_pll_calc_factors(req->rate, req->best_parent_rate, &nr, &nf, &od);
-
-	req->rate = ccu_pll_calc_freq(req->best_parent_rate, nr, nf, od);
-
-	return 0;
-}
-
-/*
- * This method is used for PLLs, which support the on-the-fly dividers
- * adjustment. So there is no need in gating such clocks.
- */
-static int ccu_pll_set_rate_reset(struct clk_hw *hw, unsigned long rate,
-				  unsigned long parent_rate)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	unsigned long nr, nf, od;
-	unsigned long flags;
-	u32 mask, val;
-	int ret;
-
-	ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
-
-	mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
-	       CCU_PLL_CTL_CLKOD_MASK;
-	val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
-	      FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
-	      FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
-	ret = ccu_pll_reset(pll, parent_rate, nr);
-	spin_unlock_irqrestore(&pll->lock, flags);
-	if (ret)
-		pr_err("PLL '%s' reset timed out\n", clk_hw_get_name(hw));
-
-	return ret;
-}
-
-/*
- * This method is used for PLLs, which don't support the on-the-fly dividers
- * adjustment. So the corresponding clocks are supposed to be gated first.
- */
-static int ccu_pll_set_rate_norst(struct clk_hw *hw, unsigned long rate,
-				  unsigned long parent_rate)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	unsigned long nr, nf, od;
-	unsigned long flags;
-	u32 mask, val;
-
-	ccu_pll_calc_factors(rate, parent_rate, &nr, &nf, &od);
-
-	/*
-	 * Disable PLL if it was enabled by default or left enabled by the
-	 * system bootloader.
-	 */
-	mask = CCU_PLL_CTL_CLKR_MASK | CCU_PLL_CTL_CLKF_MASK |
-	       CCU_PLL_CTL_CLKOD_MASK | CCU_PLL_CTL_EN;
-	val = FIELD_PREP(CCU_PLL_CTL_CLKR_MASK, nr - 1) |
-	      FIELD_PREP(CCU_PLL_CTL_CLKF_MASK, nf - 1) |
-	      FIELD_PREP(CCU_PLL_CTL_CLKOD_MASK, od - 1);
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl, mask, val);
-	spin_unlock_irqrestore(&pll->lock, flags);
-
-	return 0;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-struct ccu_pll_dbgfs_bit {
-	struct ccu_pll *pll;
-	const char *name;
-	unsigned int reg;
-	u32 mask;
-};
-
-struct ccu_pll_dbgfs_fld {
-	struct ccu_pll *pll;
-	const char *name;
-	unsigned int reg;
-	unsigned int lsb;
-	u32 mask;
-	u32 min;
-	u32 max;
-};
-
-#define CCU_PLL_DBGFS_BIT_ATTR(_name, _reg, _mask)	\
-	{						\
-		.name = _name,				\
-		.reg = _reg,				\
-		.mask = _mask				\
-	}
-
-#define CCU_PLL_DBGFS_FLD_ATTR(_name, _reg, _lsb, _mask, _min, _max)	\
-	{								\
-		.name = _name,						\
-		.reg = _reg,						\
-		.lsb = _lsb,						\
-		.mask = _mask,						\
-		.min = _min,						\
-		.max = _max						\
-	}
-
-static const struct ccu_pll_dbgfs_bit ccu_pll_bits[] = {
-	CCU_PLL_DBGFS_BIT_ATTR("pll_en", CCU_PLL_CTL, CCU_PLL_CTL_EN),
-	CCU_PLL_DBGFS_BIT_ATTR("pll_rst", CCU_PLL_CTL, CCU_PLL_CTL_RST),
-	CCU_PLL_DBGFS_BIT_ATTR("pll_bypass", CCU_PLL_CTL, CCU_PLL_CTL_BYPASS),
-	CCU_PLL_DBGFS_BIT_ATTR("pll_lock", CCU_PLL_CTL, CCU_PLL_CTL_LOCK)
-};
-
-#define CCU_PLL_DBGFS_BIT_NUM	ARRAY_SIZE(ccu_pll_bits)
-
-static const struct ccu_pll_dbgfs_fld ccu_pll_flds[] = {
-	CCU_PLL_DBGFS_FLD_ATTR("pll_nr", CCU_PLL_CTL, CCU_PLL_CTL_CLKR_FLD,
-				CCU_PLL_CTL_CLKR_MASK, 1, CCU_PLL_NR_MAX),
-	CCU_PLL_DBGFS_FLD_ATTR("pll_nf", CCU_PLL_CTL, CCU_PLL_CTL_CLKF_FLD,
-				CCU_PLL_CTL_CLKF_MASK, 1, CCU_PLL_NF_MAX),
-	CCU_PLL_DBGFS_FLD_ATTR("pll_od", CCU_PLL_CTL, CCU_PLL_CTL_CLKOD_FLD,
-				CCU_PLL_CTL_CLKOD_MASK, 1, CCU_PLL_OD_MAX),
-	CCU_PLL_DBGFS_FLD_ATTR("pll_nb", CCU_PLL_CTL1, CCU_PLL_CTL1_BWADJ_FLD,
-				CCU_PLL_CTL1_BWADJ_MASK, 1, CCU_PLL_NB_MAX)
-};
-
-#define CCU_PLL_DBGFS_FLD_NUM	ARRAY_SIZE(ccu_pll_flds)
-
-/*
- * It can be dangerous to change the PLL settings behind clock framework back,
- * therefore we don't provide any kernel config based compile time option for
- * this feature to enable.
- */
-#undef CCU_PLL_ALLOW_WRITE_DEBUGFS
-#ifdef CCU_PLL_ALLOW_WRITE_DEBUGFS
-
-static int ccu_pll_dbgfs_bit_set(void *priv, u64 val)
-{
-	const struct ccu_pll_dbgfs_bit *bit = priv;
-	struct ccu_pll *pll = bit->pll;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl + bit->reg,
-			   bit->mask, val ? bit->mask : 0);
-	spin_unlock_irqrestore(&pll->lock, flags);
-
-	return 0;
-}
-
-static int ccu_pll_dbgfs_fld_set(void *priv, u64 val)
-{
-	struct ccu_pll_dbgfs_fld *fld = priv;
-	struct ccu_pll *pll = fld->pll;
-	unsigned long flags;
-	u32 data;
-
-	val = clamp_t(u64, val, fld->min, fld->max);
-	data = ((val - 1) << fld->lsb) & fld->mask;
-
-	spin_lock_irqsave(&pll->lock, flags);
-	regmap_update_bits(pll->sys_regs, pll->reg_ctl + fld->reg, fld->mask,
-			   data);
-	spin_unlock_irqrestore(&pll->lock, flags);
-
-	return 0;
-}
-
-#define ccu_pll_dbgfs_mode	0644
-
-#else /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
-
-#define ccu_pll_dbgfs_bit_set	NULL
-#define ccu_pll_dbgfs_fld_set	NULL
-#define ccu_pll_dbgfs_mode	0444
-
-#endif /* !CCU_PLL_ALLOW_WRITE_DEBUGFS */
-
-static int ccu_pll_dbgfs_bit_get(void *priv, u64 *val)
-{
-	struct ccu_pll_dbgfs_bit *bit = priv;
-	struct ccu_pll *pll = bit->pll;
-	u32 data = 0;
-
-	regmap_read(pll->sys_regs, pll->reg_ctl + bit->reg, &data);
-	*val = !!(data & bit->mask);
-
-	return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_bit_fops,
-	ccu_pll_dbgfs_bit_get, ccu_pll_dbgfs_bit_set, "%llu\n");
-
-static int ccu_pll_dbgfs_fld_get(void *priv, u64 *val)
-{
-	struct ccu_pll_dbgfs_fld *fld = priv;
-	struct ccu_pll *pll = fld->pll;
-	u32 data = 0;
-
-	regmap_read(pll->sys_regs, pll->reg_ctl + fld->reg, &data);
-	*val = ((data & fld->mask) >> fld->lsb) + 1;
-
-	return 0;
-}
-DEFINE_DEBUGFS_ATTRIBUTE(ccu_pll_dbgfs_fld_fops,
-	ccu_pll_dbgfs_fld_get, ccu_pll_dbgfs_fld_set, "%llu\n");
-
-static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry)
-{
-	struct ccu_pll *pll = to_ccu_pll(hw);
-	struct ccu_pll_dbgfs_bit *bits;
-	struct ccu_pll_dbgfs_fld *flds;
-	int idx;
-
-	bits = kzalloc_objs(*bits, CCU_PLL_DBGFS_BIT_NUM);
-	if (!bits)
-		return;
-
-	for (idx = 0; idx < CCU_PLL_DBGFS_BIT_NUM; ++idx) {
-		bits[idx] = ccu_pll_bits[idx];
-		bits[idx].pll = pll;
-
-		debugfs_create_file_unsafe(bits[idx].name, ccu_pll_dbgfs_mode,
-					   dentry, &bits[idx],
-					   &ccu_pll_dbgfs_bit_fops);
-	}
-
-	flds = kzalloc_objs(*flds, CCU_PLL_DBGFS_FLD_NUM);
-	if (!flds)
-		return;
-
-	for (idx = 0; idx < CCU_PLL_DBGFS_FLD_NUM; ++idx) {
-		flds[idx] = ccu_pll_flds[idx];
-		flds[idx].pll = pll;
-
-		debugfs_create_file_unsafe(flds[idx].name, ccu_pll_dbgfs_mode,
-					   dentry, &flds[idx],
-					   &ccu_pll_dbgfs_fld_fops);
-	}
-}
-
-#else /* !CONFIG_DEBUG_FS */
-
-#define ccu_pll_debug_init NULL
-
-#endif /* !CONFIG_DEBUG_FS */
-
-static const struct clk_ops ccu_pll_gate_to_set_ops = {
-	.enable = ccu_pll_enable,
-	.disable = ccu_pll_disable,
-	.is_enabled = ccu_pll_is_enabled,
-	.recalc_rate = ccu_pll_recalc_rate,
-	.determine_rate = ccu_pll_determine_rate,
-	.set_rate = ccu_pll_set_rate_norst,
-	.debug_init = ccu_pll_debug_init
-};
-
-static const struct clk_ops ccu_pll_straight_set_ops = {
-	.enable = ccu_pll_enable,
-	.disable = ccu_pll_disable,
-	.is_enabled = ccu_pll_is_enabled,
-	.recalc_rate = ccu_pll_recalc_rate,
-	.determine_rate = ccu_pll_determine_rate,
-	.set_rate = ccu_pll_set_rate_reset,
-	.debug_init = ccu_pll_debug_init
-};
-
-struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init)
-{
-	struct clk_parent_data parent_data = { };
-	struct clk_init_data hw_init = { };
-	struct ccu_pll *pll;
-	int ret;
-
-	if (!pll_init)
-		return ERR_PTR(-EINVAL);
-
-	pll = kzalloc_obj(*pll);
-	if (!pll)
-		return ERR_PTR(-ENOMEM);
-
-	/*
-	 * Note since Baikal-T1 System Controller registers are MMIO-backed
-	 * we won't check the regmap IO operations return status, because it
-	 * must be zero anyway.
-	 */
-	pll->hw.init = &hw_init;
-	pll->reg_ctl = pll_init->base + CCU_PLL_CTL;
-	pll->reg_ctl1 = pll_init->base + CCU_PLL_CTL1;
-	pll->sys_regs = pll_init->sys_regs;
-	pll->id = pll_init->id;
-	spin_lock_init(&pll->lock);
-
-	hw_init.name = pll_init->name;
-	hw_init.flags = pll_init->flags;
-
-	if (hw_init.flags & CLK_SET_RATE_GATE)
-		hw_init.ops = &ccu_pll_gate_to_set_ops;
-	else
-		hw_init.ops = &ccu_pll_straight_set_ops;
-
-	if (!pll_init->parent_name) {
-		ret = -EINVAL;
-		goto err_free_pll;
-	}
-	parent_data.fw_name = pll_init->parent_name;
-	hw_init.parent_data = &parent_data;
-	hw_init.num_parents = 1;
-
-	ret = of_clk_hw_register(pll_init->np, &pll->hw);
-	if (ret)
-		goto err_free_pll;
-
-	return pll;
-
-err_free_pll:
-	kfree(pll);
-
-	return ERR_PTR(ret);
-}
-
-void ccu_pll_hw_unregister(struct ccu_pll *pll)
-{
-	clk_hw_unregister(&pll->hw);
-
-	kfree(pll);
-}
diff --git a/drivers/clk/baikal-t1/ccu-pll.h b/drivers/clk/baikal-t1/ccu-pll.h
deleted file mode 100644
index a71bfd7..0000000
--- a/drivers/clk/baikal-t1/ccu-pll.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Baikal-T1 CCU PLL interface driver
- */
-#ifndef __CLK_BT1_CCU_PLL_H__
-#define __CLK_BT1_CCU_PLL_H__
-
-#include <linux/clk-provider.h>
-#include <linux/spinlock.h>
-#include <linux/regmap.h>
-#include <linux/bits.h>
-#include <linux/of.h>
-
-/*
- * CCU PLL private flags
- * @CCU_PLL_BASIC: Basic PLL required by the kernel as early as possible.
- */
-#define CCU_PLL_BASIC		BIT(0)
-
-/*
- * struct ccu_pll_init_data - CCU PLL initialization data
- * @id: Clock private identifier.
- * @name: Clocks name.
- * @parent_name: Clocks parent name in a fw node.
- * @base: PLL registers base address with respect to the sys_regs base.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @np: Pointer to the node describing the CCU PLLs.
- * @flags: PLL clock flags.
- * @features: PLL private features.
- */
-struct ccu_pll_init_data {
-	unsigned int id;
-	const char *name;
-	const char *parent_name;
-	unsigned int base;
-	struct regmap *sys_regs;
-	struct device_node *np;
-	unsigned long flags;
-	unsigned long features;
-};
-
-/*
- * struct ccu_pll - CCU PLL descriptor
- * @hw: clk_hw of the PLL.
- * @id: Clock private identifier.
- * @reg_ctl: PLL control register base.
- * @reg_ctl1: PLL control1 register base.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @lock: PLL state change spin-lock.
- */
-struct ccu_pll {
-	struct clk_hw hw;
-	unsigned int id;
-	unsigned int reg_ctl;
-	unsigned int reg_ctl1;
-	struct regmap *sys_regs;
-	spinlock_t lock;
-};
-#define to_ccu_pll(_hw) container_of(_hw, struct ccu_pll, hw)
-
-static inline struct clk_hw *ccu_pll_get_clk_hw(struct ccu_pll *pll)
-{
-	return pll ? &pll->hw : NULL;
-}
-
-struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *init);
-
-void ccu_pll_hw_unregister(struct ccu_pll *pll);
-
-#endif /* __CLK_BT1_CCU_PLL_H__ */
diff --git a/drivers/clk/baikal-t1/ccu-rst.c b/drivers/clk/baikal-t1/ccu-rst.c
deleted file mode 100644
index 969e5de..0000000
--- a/drivers/clk/baikal-t1/ccu-rst.c
+++ /dev/null
@@ -1,217 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *
- * Baikal-T1 CCU Resets interface driver
- */
-
-#define pr_fmt(fmt) "bt1-ccu-rst: " fmt
-
-#include <linux/bits.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/printk.h>
-#include <linux/regmap.h>
-#include <linux/reset-controller.h>
-#include <linux/slab.h>
-
-#include <dt-bindings/reset/bt1-ccu.h>
-
-#include "ccu-rst.h"
-
-#define CCU_AXI_MAIN_BASE		0x030
-#define CCU_AXI_DDR_BASE		0x034
-#define CCU_AXI_SATA_BASE		0x038
-#define CCU_AXI_GMAC0_BASE		0x03C
-#define CCU_AXI_GMAC1_BASE		0x040
-#define CCU_AXI_XGMAC_BASE		0x044
-#define CCU_AXI_PCIE_M_BASE		0x048
-#define CCU_AXI_PCIE_S_BASE		0x04C
-#define CCU_AXI_USB_BASE		0x050
-#define CCU_AXI_HWA_BASE		0x054
-#define CCU_AXI_SRAM_BASE		0x058
-
-#define CCU_SYS_DDR_BASE		0x02c
-#define CCU_SYS_SATA_REF_BASE		0x060
-#define CCU_SYS_APB_BASE		0x064
-#define CCU_SYS_PCIE_BASE		0x144
-
-#define CCU_RST_DELAY_US		1
-
-#define CCU_RST_TRIG(_base, _ofs)		\
-	{					\
-		.type = CCU_RST_TRIG,		\
-		.base = _base,			\
-		.mask = BIT(_ofs),		\
-	}
-
-#define CCU_RST_DIR(_base, _ofs)		\
-	{					\
-		.type = CCU_RST_DIR,		\
-		.base = _base,			\
-		.mask = BIT(_ofs),		\
-	}
-
-struct ccu_rst_info {
-	enum ccu_rst_type type;
-	unsigned int base;
-	unsigned int mask;
-};
-
-/*
- * Each AXI-bus clock divider is equipped with the corresponding clock-consumer
- * domain reset (it's self-deasserted reset control).
- */
-static const struct ccu_rst_info axi_rst_info[] = {
-	[CCU_AXI_MAIN_RST] = CCU_RST_TRIG(CCU_AXI_MAIN_BASE, 1),
-	[CCU_AXI_DDR_RST] = CCU_RST_TRIG(CCU_AXI_DDR_BASE, 1),
-	[CCU_AXI_SATA_RST] = CCU_RST_TRIG(CCU_AXI_SATA_BASE, 1),
-	[CCU_AXI_GMAC0_RST] = CCU_RST_TRIG(CCU_AXI_GMAC0_BASE, 1),
-	[CCU_AXI_GMAC1_RST] = CCU_RST_TRIG(CCU_AXI_GMAC1_BASE, 1),
-	[CCU_AXI_XGMAC_RST] = CCU_RST_TRIG(CCU_AXI_XGMAC_BASE, 1),
-	[CCU_AXI_PCIE_M_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_M_BASE, 1),
-	[CCU_AXI_PCIE_S_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_S_BASE, 1),
-	[CCU_AXI_USB_RST] = CCU_RST_TRIG(CCU_AXI_USB_BASE, 1),
-	[CCU_AXI_HWA_RST] = CCU_RST_TRIG(CCU_AXI_HWA_BASE, 1),
-	[CCU_AXI_SRAM_RST] = CCU_RST_TRIG(CCU_AXI_SRAM_BASE, 1),
-};
-
-/*
- * SATA reference clock domain and APB-bus domain are connected with the
- * sefl-deasserted reset control, which can be activated via the corresponding
- * clock divider register. DDR and PCIe sub-domains can be reset with directly
- * controlled reset signals. Resetting the DDR controller though won't end up
- * well while the Linux kernel is working.
- */
-static const struct ccu_rst_info sys_rst_info[] = {
-	[CCU_SYS_SATA_REF_RST] = CCU_RST_TRIG(CCU_SYS_SATA_REF_BASE, 1),
-	[CCU_SYS_APB_RST] = CCU_RST_TRIG(CCU_SYS_APB_BASE, 1),
-	[CCU_SYS_DDR_FULL_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 1),
-	[CCU_SYS_DDR_INIT_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 2),
-	[CCU_SYS_PCIE_PCS_PHY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 0),
-	[CCU_SYS_PCIE_PIPE0_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 4),
-	[CCU_SYS_PCIE_CORE_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 8),
-	[CCU_SYS_PCIE_PWR_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 9),
-	[CCU_SYS_PCIE_STICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 10),
-	[CCU_SYS_PCIE_NSTICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 11),
-	[CCU_SYS_PCIE_HOT_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 12),
-};
-
-static int ccu_rst_reset(struct reset_controller_dev *rcdev, unsigned long idx)
-{
-	struct ccu_rst *rst = to_ccu_rst(rcdev);
-	const struct ccu_rst_info *info = &rst->rsts_info[idx];
-
-	if (info->type != CCU_RST_TRIG)
-		return -EOPNOTSUPP;
-
-	regmap_update_bits(rst->sys_regs, info->base, info->mask, info->mask);
-
-	/* The next delay must be enough to cover all the resets. */
-	udelay(CCU_RST_DELAY_US);
-
-	return 0;
-}
-
-static int ccu_rst_set(struct reset_controller_dev *rcdev,
-		       unsigned long idx, bool high)
-{
-	struct ccu_rst *rst = to_ccu_rst(rcdev);
-	const struct ccu_rst_info *info = &rst->rsts_info[idx];
-
-	if (info->type != CCU_RST_DIR)
-		return high ? -EOPNOTSUPP : 0;
-
-	return regmap_update_bits(rst->sys_regs, info->base,
-				  info->mask, high ? info->mask : 0);
-}
-
-static int ccu_rst_assert(struct reset_controller_dev *rcdev,
-			  unsigned long idx)
-{
-	return ccu_rst_set(rcdev, idx, true);
-}
-
-static int ccu_rst_deassert(struct reset_controller_dev *rcdev,
-			    unsigned long idx)
-{
-	return ccu_rst_set(rcdev, idx, false);
-}
-
-static int ccu_rst_status(struct reset_controller_dev *rcdev,
-			  unsigned long idx)
-{
-	struct ccu_rst *rst = to_ccu_rst(rcdev);
-	const struct ccu_rst_info *info = &rst->rsts_info[idx];
-	u32 val;
-
-	if (info->type != CCU_RST_DIR)
-		return -EOPNOTSUPP;
-
-	regmap_read(rst->sys_regs, info->base, &val);
-
-	return !!(val & info->mask);
-}
-
-static const struct reset_control_ops ccu_rst_ops = {
-	.reset = ccu_rst_reset,
-	.assert = ccu_rst_assert,
-	.deassert = ccu_rst_deassert,
-	.status = ccu_rst_status,
-};
-
-struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init)
-{
-	struct ccu_rst *rst;
-	int ret;
-
-	if (!rst_init)
-		return ERR_PTR(-EINVAL);
-
-	rst = kzalloc_obj(*rst);
-	if (!rst)
-		return ERR_PTR(-ENOMEM);
-
-	rst->sys_regs = rst_init->sys_regs;
-	if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-axi")) {
-		rst->rcdev.nr_resets = ARRAY_SIZE(axi_rst_info);
-		rst->rsts_info = axi_rst_info;
-	} else if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-sys")) {
-		rst->rcdev.nr_resets = ARRAY_SIZE(sys_rst_info);
-		rst->rsts_info = sys_rst_info;
-	} else {
-		pr_err("Incompatible DT node '%s' specified\n",
-		       of_node_full_name(rst_init->np));
-		ret = -EINVAL;
-		goto err_kfree_rst;
-	}
-
-	rst->rcdev.owner = THIS_MODULE;
-	rst->rcdev.ops = &ccu_rst_ops;
-	rst->rcdev.of_node = rst_init->np;
-
-	ret = reset_controller_register(&rst->rcdev);
-	if (ret) {
-		pr_err("Couldn't register '%s' reset controller\n",
-		       of_node_full_name(rst_init->np));
-		goto err_kfree_rst;
-	}
-
-	return rst;
-
-err_kfree_rst:
-	kfree(rst);
-
-	return ERR_PTR(ret);
-}
-
-void ccu_rst_hw_unregister(struct ccu_rst *rst)
-{
-	reset_controller_unregister(&rst->rcdev);
-
-	kfree(rst);
-}
diff --git a/drivers/clk/baikal-t1/ccu-rst.h b/drivers/clk/baikal-t1/ccu-rst.h
deleted file mode 100644
index d6e8b2f..0000000
--- a/drivers/clk/baikal-t1/ccu-rst.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC
- *
- * Baikal-T1 CCU Resets interface driver
- */
-#ifndef __CLK_BT1_CCU_RST_H__
-#define __CLK_BT1_CCU_RST_H__
-
-#include <linux/of.h>
-#include <linux/regmap.h>
-#include <linux/reset-controller.h>
-
-struct ccu_rst_info;
-
-/*
- * enum ccu_rst_type - CCU Reset types
- * @CCU_RST_TRIG: Self-deasserted reset signal.
- * @CCU_RST_DIR: Directly controlled reset signal.
- */
-enum ccu_rst_type {
-	CCU_RST_TRIG,
-	CCU_RST_DIR,
-};
-
-/*
- * struct ccu_rst_init_data - CCU Resets initialization data
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @np: Pointer to the node with the System CCU block.
- */
-struct ccu_rst_init_data {
-	struct regmap *sys_regs;
-	struct device_node *np;
-};
-
-/*
- * struct ccu_rst - CCU Reset descriptor
- * @rcdev: Reset controller descriptor.
- * @sys_regs: Baikal-T1 System Controller registers map.
- * @rsts_info: Reset flag info (base address and mask).
- */
-struct ccu_rst {
-	struct reset_controller_dev rcdev;
-	struct regmap *sys_regs;
-	const struct ccu_rst_info *rsts_info;
-};
-#define to_ccu_rst(_rcdev) container_of(_rcdev, struct ccu_rst, rcdev)
-
-#ifdef CONFIG_CLK_BT1_CCU_RST
-
-struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init);
-
-void ccu_rst_hw_unregister(struct ccu_rst *rst);
-
-#else
-
-static inline
-struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *init)
-{
-	return NULL;
-}
-
-static inline void ccu_rst_hw_unregister(struct ccu_rst *rst) {}
-
-#endif
-
-#endif /* __CLK_BT1_CCU_RST_H__ */
diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c
deleted file mode 100644
index d32072e..0000000
--- a/drivers/clk/baikal-t1/clk-ccu-div.c
+++ /dev/null
@@ -1,520 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *   Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
- *
- * Baikal-T1 CCU Dividers clock driver
- */
-
-#define pr_fmt(fmt) "bt1-ccu-div: " fmt
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/clk-provider.h>
-#include <linux/reset-controller.h>
-#include <linux/mfd/syscon.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/ioport.h>
-#include <linux/regmap.h>
-
-#include <dt-bindings/clock/bt1-ccu.h>
-
-#include "ccu-div.h"
-#include "ccu-rst.h"
-
-#define CCU_AXI_MAIN_BASE		0x030
-#define CCU_AXI_DDR_BASE		0x034
-#define CCU_AXI_SATA_BASE		0x038
-#define CCU_AXI_GMAC0_BASE		0x03C
-#define CCU_AXI_GMAC1_BASE		0x040
-#define CCU_AXI_XGMAC_BASE		0x044
-#define CCU_AXI_PCIE_M_BASE		0x048
-#define CCU_AXI_PCIE_S_BASE		0x04C
-#define CCU_AXI_USB_BASE		0x050
-#define CCU_AXI_HWA_BASE		0x054
-#define CCU_AXI_SRAM_BASE		0x058
-
-#define CCU_SYS_SATA_REF_BASE		0x060
-#define CCU_SYS_APB_BASE		0x064
-#define CCU_SYS_GMAC0_BASE		0x068
-#define CCU_SYS_GMAC1_BASE		0x06C
-#define CCU_SYS_XGMAC_BASE		0x070
-#define CCU_SYS_USB_BASE		0x074
-#define CCU_SYS_PVT_BASE		0x078
-#define CCU_SYS_HWA_BASE		0x07C
-#define CCU_SYS_UART_BASE		0x084
-#define CCU_SYS_TIMER0_BASE		0x088
-#define CCU_SYS_TIMER1_BASE		0x08C
-#define CCU_SYS_TIMER2_BASE		0x090
-#define CCU_SYS_WDT_BASE		0x150
-
-#define CCU_DIV_VAR_INFO(_id, _name, _pname, _base, _width, _flags, _features) \
-	{								\
-		.id = _id,						\
-		.name = _name,						\
-		.parent_name = _pname,					\
-		.base = _base,						\
-		.type = CCU_DIV_VAR,					\
-		.width = _width,					\
-		.flags = _flags,					\
-		.features = _features					\
-	}
-
-#define CCU_DIV_GATE_INFO(_id, _name, _pname, _base, _divider)	\
-	{							\
-		.id = _id,					\
-		.name = _name,					\
-		.parent_name = _pname,				\
-		.base = _base,					\
-		.type = CCU_DIV_GATE,				\
-		.divider = _divider				\
-	}
-
-#define CCU_DIV_BUF_INFO(_id, _name, _pname, _base, _flags)	\
-	{							\
-		.id = _id,					\
-		.name = _name,					\
-		.parent_name = _pname,				\
-		.base = _base,					\
-		.type = CCU_DIV_BUF,				\
-		.flags = _flags					\
-	}
-
-#define CCU_DIV_FIXED_INFO(_id, _name, _pname, _divider)	\
-	{							\
-		.id = _id,					\
-		.name = _name,					\
-		.parent_name = _pname,				\
-		.type = CCU_DIV_FIXED,				\
-		.divider = _divider				\
-	}
-
-struct ccu_div_info {
-	unsigned int id;
-	const char *name;
-	const char *parent_name;
-	unsigned int base;
-	enum ccu_div_type type;
-	union {
-		unsigned int width;
-		unsigned int divider;
-	};
-	unsigned long flags;
-	unsigned long features;
-};
-
-struct ccu_div_data {
-	struct device_node *np;
-	struct regmap *sys_regs;
-
-	unsigned int divs_num;
-	const struct ccu_div_info *divs_info;
-	struct ccu_div **divs;
-
-	struct ccu_rst *rsts;
-};
-
-/*
- * AXI Main Interconnect (axi_main_clk) and DDR AXI-bus (axi_ddr_clk) clocks
- * must be left enabled in any case, since former one is responsible for
- * clocking a bus between CPU cores and the rest of the SoC components, while
- * the later is clocking the AXI-bus between DDR controller and the Main
- * Interconnect. So should any of these clocks get to be disabled, the system
- * will literally stop working. That's why we marked them as critical.
- */
-static const struct ccu_div_info axi_info[] = {
-	CCU_DIV_VAR_INFO(CCU_AXI_MAIN_CLK, "axi_main_clk", "pcie_clk",
-			 CCU_AXI_MAIN_BASE, 4,
-			 CLK_IS_CRITICAL, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_DDR_CLK, "axi_ddr_clk", "sata_clk",
-			 CCU_AXI_DDR_BASE, 4,
-			 CLK_IS_CRITICAL | CLK_SET_RATE_GATE,
-			 CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_SATA_CLK, "axi_sata_clk", "sata_clk",
-			 CCU_AXI_SATA_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_GMAC0_CLK, "axi_gmac0_clk", "eth_clk",
-			 CCU_AXI_GMAC0_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_GMAC1_CLK, "axi_gmac1_clk", "eth_clk",
-			 CCU_AXI_GMAC1_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_XGMAC_CLK, "axi_xgmac_clk", "eth_clk",
-			 CCU_AXI_XGMAC_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_PCIE_M_CLK, "axi_pcie_m_clk", "pcie_clk",
-			 CCU_AXI_PCIE_M_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_PCIE_S_CLK, "axi_pcie_s_clk", "pcie_clk",
-			 CCU_AXI_PCIE_S_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_USB_CLK, "axi_usb_clk", "sata_clk",
-			 CCU_AXI_USB_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_HWA_CLK, "axi_hwa_clk", "sata_clk",
-			 CCU_AXI_HWA_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_VAR_INFO(CCU_AXI_SRAM_CLK, "axi_sram_clk", "eth_clk",
-			 CCU_AXI_SRAM_BASE, 4,
-			 CLK_SET_RATE_GATE, CCU_DIV_RESET_DOMAIN)
-};
-
-/*
- * APB-bus clock is marked as critical since it's a main communication bus
- * for the SoC devices registers IO-operations.
- */
-static const struct ccu_div_info sys_info[] = {
-	CCU_DIV_VAR_INFO(CCU_SYS_SATA_CLK, "sys_sata_clk",
-			 "sata_clk", CCU_SYS_SATA_REF_BASE, 4,
-			 CLK_SET_RATE_GATE,
-			 CCU_DIV_SKIP_ONE | CCU_DIV_LOCK_SHIFTED |
-			 CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_BUF_INFO(CCU_SYS_SATA_REF_CLK, "sys_sata_ref_clk",
-			 "sys_sata_clk", CCU_SYS_SATA_REF_BASE,
-			 CLK_SET_RATE_PARENT),
-	CCU_DIV_VAR_INFO(CCU_SYS_APB_CLK, "sys_apb_clk",
-			 "pcie_clk", CCU_SYS_APB_BASE, 5,
-			 CLK_IS_CRITICAL, CCU_DIV_BASIC | CCU_DIV_RESET_DOMAIN),
-	CCU_DIV_GATE_INFO(CCU_SYS_GMAC0_TX_CLK, "sys_gmac0_tx_clk",
-			  "eth_clk", CCU_SYS_GMAC0_BASE, 5),
-	CCU_DIV_FIXED_INFO(CCU_SYS_GMAC0_PTP_CLK, "sys_gmac0_ptp_clk",
-			   "eth_clk", 10),
-	CCU_DIV_GATE_INFO(CCU_SYS_GMAC1_TX_CLK, "sys_gmac1_tx_clk",
-			  "eth_clk", CCU_SYS_GMAC1_BASE, 5),
-	CCU_DIV_FIXED_INFO(CCU_SYS_GMAC1_PTP_CLK, "sys_gmac1_ptp_clk",
-			   "eth_clk", 10),
-	CCU_DIV_GATE_INFO(CCU_SYS_XGMAC_CLK, "sys_xgmac_clk",
-			  "eth_clk", CCU_SYS_XGMAC_BASE, 1),
-	CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_REF_CLK, "sys_xgmac_ref_clk",
-			   "sys_xgmac_clk", 8),
-	CCU_DIV_FIXED_INFO(CCU_SYS_XGMAC_PTP_CLK, "sys_xgmac_ptp_clk",
-			   "sys_xgmac_clk", 8),
-	CCU_DIV_GATE_INFO(CCU_SYS_USB_CLK, "sys_usb_clk",
-			  "eth_clk", CCU_SYS_USB_BASE, 10),
-	CCU_DIV_VAR_INFO(CCU_SYS_PVT_CLK, "sys_pvt_clk",
-			 "ref_clk", CCU_SYS_PVT_BASE, 5,
-			 CLK_SET_RATE_GATE, 0),
-	CCU_DIV_VAR_INFO(CCU_SYS_HWA_CLK, "sys_hwa_clk",
-			 "sata_clk", CCU_SYS_HWA_BASE, 4,
-			 CLK_SET_RATE_GATE, 0),
-	CCU_DIV_VAR_INFO(CCU_SYS_UART_CLK, "sys_uart_clk",
-			 "eth_clk", CCU_SYS_UART_BASE, 17,
-			 CLK_SET_RATE_GATE, 0),
-	CCU_DIV_FIXED_INFO(CCU_SYS_I2C1_CLK, "sys_i2c1_clk",
-			   "eth_clk", 10),
-	CCU_DIV_FIXED_INFO(CCU_SYS_I2C2_CLK, "sys_i2c2_clk",
-			   "eth_clk", 10),
-	CCU_DIV_FIXED_INFO(CCU_SYS_GPIO_CLK, "sys_gpio_clk",
-			   "ref_clk", 25),
-	CCU_DIV_VAR_INFO(CCU_SYS_TIMER0_CLK, "sys_timer0_clk",
-			 "ref_clk", CCU_SYS_TIMER0_BASE, 17,
-			 CLK_SET_RATE_GATE, CCU_DIV_BASIC),
-	CCU_DIV_VAR_INFO(CCU_SYS_TIMER1_CLK, "sys_timer1_clk",
-			 "ref_clk", CCU_SYS_TIMER1_BASE, 17,
-			 CLK_SET_RATE_GATE, CCU_DIV_BASIC),
-	CCU_DIV_VAR_INFO(CCU_SYS_TIMER2_CLK, "sys_timer2_clk",
-			 "ref_clk", CCU_SYS_TIMER2_BASE, 17,
-			 CLK_SET_RATE_GATE, CCU_DIV_BASIC),
-	CCU_DIV_VAR_INFO(CCU_SYS_WDT_CLK, "sys_wdt_clk",
-			 "eth_clk", CCU_SYS_WDT_BASE, 17,
-			 CLK_SET_RATE_GATE, CCU_DIV_SKIP_ONE_TO_THREE)
-};
-
-static struct ccu_div_data *axi_data;
-static struct ccu_div_data *sys_data;
-
-static void ccu_div_set_data(struct ccu_div_data *data)
-{
-	struct device_node *np = data->np;
-
-	if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
-		axi_data = data;
-	else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
-		sys_data = data;
-	else
-		pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
-}
-
-static struct ccu_div_data *ccu_div_get_data(struct device_node *np)
-{
-	if (of_device_is_compatible(np, "baikal,bt1-ccu-axi"))
-		return axi_data;
-	else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys"))
-		return sys_data;
-
-	pr_err("Invalid DT node '%s' specified\n", of_node_full_name(np));
-
-	return NULL;
-}
-
-static struct ccu_div *ccu_div_find_desc(struct ccu_div_data *data,
-					 unsigned int clk_id)
-{
-	int idx;
-
-	for (idx = 0; idx < data->divs_num; ++idx) {
-		if (data->divs_info[idx].id == clk_id)
-			return data->divs[idx];
-	}
-
-	return ERR_PTR(-EINVAL);
-}
-
-static struct ccu_div_data *ccu_div_create_data(struct device_node *np)
-{
-	struct ccu_div_data *data;
-	int ret;
-
-	data = kzalloc_obj(*data);
-	if (!data)
-		return ERR_PTR(-ENOMEM);
-
-	data->np = np;
-	if (of_device_is_compatible(np, "baikal,bt1-ccu-axi")) {
-		data->divs_num = ARRAY_SIZE(axi_info);
-		data->divs_info = axi_info;
-	} else if (of_device_is_compatible(np, "baikal,bt1-ccu-sys")) {
-		data->divs_num = ARRAY_SIZE(sys_info);
-		data->divs_info = sys_info;
-	} else {
-		pr_err("Incompatible DT node '%s' specified\n",
-			of_node_full_name(np));
-		ret = -EINVAL;
-		goto err_kfree_data;
-	}
-
-	data->divs = kzalloc_objs(*data->divs, data->divs_num);
-	if (!data->divs) {
-		ret = -ENOMEM;
-		goto err_kfree_data;
-	}
-
-	return data;
-
-err_kfree_data:
-	kfree(data);
-
-	return ERR_PTR(ret);
-}
-
-static void ccu_div_free_data(struct ccu_div_data *data)
-{
-	kfree(data->divs);
-
-	kfree(data);
-}
-
-static int ccu_div_find_sys_regs(struct ccu_div_data *data)
-{
-	data->sys_regs = syscon_node_to_regmap(data->np->parent);
-	if (IS_ERR(data->sys_regs)) {
-		pr_err("Failed to find syscon regs for '%s'\n",
-			of_node_full_name(data->np));
-		return PTR_ERR(data->sys_regs);
-	}
-
-	return 0;
-}
-
-static struct clk_hw *ccu_div_of_clk_hw_get(struct of_phandle_args *clkspec,
-					    void *priv)
-{
-	struct ccu_div_data *data = priv;
-	struct ccu_div *div;
-	unsigned int clk_id;
-
-	clk_id = clkspec->args[0];
-	div = ccu_div_find_desc(data, clk_id);
-	if (IS_ERR(div)) {
-		if (div != ERR_PTR(-EPROBE_DEFER))
-			pr_info("Invalid clock ID %d specified\n", clk_id);
-
-		return ERR_CAST(div);
-	}
-
-	return ccu_div_get_clk_hw(div);
-}
-
-static int ccu_div_clk_register(struct ccu_div_data *data, bool defer)
-{
-	int idx, ret;
-
-	for (idx = 0; idx < data->divs_num; ++idx) {
-		const struct ccu_div_info *info = &data->divs_info[idx];
-		struct ccu_div_init_data init = {0};
-
-		if (!!(info->features & CCU_DIV_BASIC) ^ defer) {
-			if (!data->divs[idx])
-				data->divs[idx] = ERR_PTR(-EPROBE_DEFER);
-
-			continue;
-		}
-
-		init.id = info->id;
-		init.name = info->name;
-		init.parent_name = info->parent_name;
-		init.np = data->np;
-		init.type = info->type;
-		init.flags = info->flags;
-		init.features = info->features;
-
-		if (init.type == CCU_DIV_VAR) {
-			init.base = info->base;
-			init.sys_regs = data->sys_regs;
-			init.width = info->width;
-		} else if (init.type == CCU_DIV_GATE) {
-			init.base = info->base;
-			init.sys_regs = data->sys_regs;
-			init.divider = info->divider;
-		} else if (init.type == CCU_DIV_BUF) {
-			init.base = info->base;
-			init.sys_regs = data->sys_regs;
-		} else {
-			init.divider = info->divider;
-		}
-
-		data->divs[idx] = ccu_div_hw_register(&init);
-		if (IS_ERR(data->divs[idx])) {
-			ret = PTR_ERR(data->divs[idx]);
-			pr_err("Couldn't register divider '%s' hw\n",
-				init.name);
-			goto err_hw_unregister;
-		}
-	}
-
-	return 0;
-
-err_hw_unregister:
-	for (--idx; idx >= 0; --idx) {
-		if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
-			continue;
-
-		ccu_div_hw_unregister(data->divs[idx]);
-	}
-
-	return ret;
-}
-
-static void ccu_div_clk_unregister(struct ccu_div_data *data, bool defer)
-{
-	int idx;
-
-	/* Uninstall only the clocks registered on the specified stage */
-	for (idx = 0; idx < data->divs_num; ++idx) {
-		if (!!(data->divs_info[idx].features & CCU_DIV_BASIC) ^ defer)
-			continue;
-
-		ccu_div_hw_unregister(data->divs[idx]);
-	}
-}
-
-static int ccu_div_of_register(struct ccu_div_data *data)
-{
-	int ret;
-
-	ret = of_clk_add_hw_provider(data->np, ccu_div_of_clk_hw_get, data);
-	if (ret) {
-		pr_err("Couldn't register dividers '%s' clock provider\n",
-		       of_node_full_name(data->np));
-	}
-
-	return ret;
-}
-
-static int ccu_div_rst_register(struct ccu_div_data *data)
-{
-	struct ccu_rst_init_data init = {0};
-
-	init.sys_regs = data->sys_regs;
-	init.np = data->np;
-
-	data->rsts = ccu_rst_hw_register(&init);
-	if (IS_ERR(data->rsts)) {
-		pr_err("Couldn't register divider '%s' reset controller\n",
-			of_node_full_name(data->np));
-		return PTR_ERR(data->rsts);
-	}
-
-	return 0;
-}
-
-static int ccu_div_probe(struct platform_device *pdev)
-{
-	struct ccu_div_data *data;
-	int ret;
-
-	data = ccu_div_get_data(dev_of_node(&pdev->dev));
-	if (!data)
-		return -EINVAL;
-
-	ret = ccu_div_clk_register(data, false);
-	if (ret)
-		return ret;
-
-	ret = ccu_div_rst_register(data);
-	if (ret)
-		goto err_clk_unregister;
-
-	return 0;
-
-err_clk_unregister:
-	ccu_div_clk_unregister(data, false);
-
-	return ret;
-}
-
-static const struct of_device_id ccu_div_of_match[] = {
-	{ .compatible = "baikal,bt1-ccu-axi" },
-	{ .compatible = "baikal,bt1-ccu-sys" },
-	{ }
-};
-
-static struct platform_driver ccu_div_driver = {
-	.probe  = ccu_div_probe,
-	.driver = {
-		.name = "clk-ccu-div",
-		.of_match_table = ccu_div_of_match,
-		.suppress_bind_attrs = true,
-	},
-};
-builtin_platform_driver(ccu_div_driver);
-
-static __init void ccu_div_init(struct device_node *np)
-{
-	struct ccu_div_data *data;
-	int ret;
-
-	data = ccu_div_create_data(np);
-	if (IS_ERR(data))
-		return;
-
-	ret = ccu_div_find_sys_regs(data);
-	if (ret)
-		goto err_free_data;
-
-	ret = ccu_div_clk_register(data, true);
-	if (ret)
-		goto err_free_data;
-
-	ret = ccu_div_of_register(data);
-	if (ret)
-		goto err_clk_unregister;
-
-	ccu_div_set_data(data);
-
-	return;
-
-err_clk_unregister:
-	ccu_div_clk_unregister(data, true);
-
-err_free_data:
-	ccu_div_free_data(data);
-}
-CLK_OF_DECLARE_DRIVER(ccu_axi, "baikal,bt1-ccu-axi", ccu_div_init);
-CLK_OF_DECLARE_DRIVER(ccu_sys, "baikal,bt1-ccu-sys", ccu_div_init);
diff --git a/drivers/clk/baikal-t1/clk-ccu-pll.c b/drivers/clk/baikal-t1/clk-ccu-pll.c
deleted file mode 100644
index e5e4a6e..0000000
--- a/drivers/clk/baikal-t1/clk-ccu-pll.c
+++ /dev/null
@@ -1,277 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC
- *
- * Authors:
- *   Serge Semin <Sergey.Semin@baikalelectronics.ru>
- *   Dmitry Dunaev <dmitry.dunaev@baikalelectronics.ru>
- *
- * Baikal-T1 CCU PLL clocks driver
- */
-
-#define pr_fmt(fmt) "bt1-ccu-pll: " fmt
-
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/clk-provider.h>
-#include <linux/mfd/syscon.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/ioport.h>
-#include <linux/regmap.h>
-
-#include <dt-bindings/clock/bt1-ccu.h>
-
-#include "ccu-pll.h"
-
-#define CCU_CPU_PLL_BASE		0x000
-#define CCU_SATA_PLL_BASE		0x008
-#define CCU_DDR_PLL_BASE		0x010
-#define CCU_PCIE_PLL_BASE		0x018
-#define CCU_ETH_PLL_BASE		0x020
-
-#define CCU_PLL_INFO(_id, _name, _pname, _base, _flags, _features)	\
-	{								\
-		.id = _id,						\
-		.name = _name,						\
-		.parent_name = _pname,					\
-		.base = _base,						\
-		.flags = _flags,					\
-		.features = _features,					\
-	}
-
-#define CCU_PLL_NUM			ARRAY_SIZE(pll_info)
-
-struct ccu_pll_info {
-	unsigned int id;
-	const char *name;
-	const char *parent_name;
-	unsigned int base;
-	unsigned long flags;
-	unsigned long features;
-};
-
-/*
- * Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of
- * CPU cores and DDR controller reference clocks, due to which they obviously
- * shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and
- * DDR controller AXI-bus clocks. If they are gated the system will be
- * unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset
- * of the corresponding subsystems. So until we aren't ready to re-initialize
- * all the devices consuming those PLLs, they will be marked as critical too.
- */
-static const struct ccu_pll_info pll_info[] = {
-	CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
-		     CLK_IS_CRITICAL, CCU_PLL_BASIC),
-	CCU_PLL_INFO(CCU_SATA_PLL, "sata_pll", "ref_clk", CCU_SATA_PLL_BASE,
-		     CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0),
-	CCU_PLL_INFO(CCU_DDR_PLL, "ddr_pll", "ref_clk", CCU_DDR_PLL_BASE,
-		     CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0),
-	CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
-		     CLK_IS_CRITICAL, CCU_PLL_BASIC),
-	CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
-		     CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0)
-};
-
-struct ccu_pll_data {
-	struct device_node *np;
-	struct regmap *sys_regs;
-	struct ccu_pll *plls[CCU_PLL_NUM];
-};
-
-static struct ccu_pll_data *pll_data;
-
-static struct ccu_pll *ccu_pll_find_desc(struct ccu_pll_data *data,
-					 unsigned int clk_id)
-{
-	int idx;
-
-	for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
-		if (pll_info[idx].id == clk_id)
-			return data->plls[idx];
-	}
-
-	return ERR_PTR(-EINVAL);
-}
-
-static struct ccu_pll_data *ccu_pll_create_data(struct device_node *np)
-{
-	struct ccu_pll_data *data;
-
-	data = kzalloc_obj(*data);
-	if (!data)
-		return ERR_PTR(-ENOMEM);
-
-	data->np = np;
-
-	return data;
-}
-
-static void ccu_pll_free_data(struct ccu_pll_data *data)
-{
-	kfree(data);
-}
-
-static int ccu_pll_find_sys_regs(struct ccu_pll_data *data)
-{
-	data->sys_regs = syscon_node_to_regmap(data->np->parent);
-	if (IS_ERR(data->sys_regs)) {
-		pr_err("Failed to find syscon regs for '%s'\n",
-			of_node_full_name(data->np));
-		return PTR_ERR(data->sys_regs);
-	}
-
-	return 0;
-}
-
-static struct clk_hw *ccu_pll_of_clk_hw_get(struct of_phandle_args *clkspec,
-					    void *priv)
-{
-	struct ccu_pll_data *data = priv;
-	struct ccu_pll *pll;
-	unsigned int clk_id;
-
-	clk_id = clkspec->args[0];
-	pll = ccu_pll_find_desc(data, clk_id);
-	if (IS_ERR(pll)) {
-		if (pll != ERR_PTR(-EPROBE_DEFER))
-			pr_info("Invalid PLL clock ID %d specified\n", clk_id);
-
-		return ERR_CAST(pll);
-	}
-
-	return ccu_pll_get_clk_hw(pll);
-}
-
-static int ccu_pll_clk_register(struct ccu_pll_data *data, bool defer)
-{
-	int idx, ret;
-
-	for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
-		const struct ccu_pll_info *info = &pll_info[idx];
-		struct ccu_pll_init_data init = {0};
-
-		/* Defer non-basic PLLs allocation for the probe stage */
-		if (!!(info->features & CCU_PLL_BASIC) ^ defer) {
-			if (!data->plls[idx])
-				data->plls[idx] = ERR_PTR(-EPROBE_DEFER);
-
-			continue;
-		}
-
-		init.id = info->id;
-		init.name = info->name;
-		init.parent_name = info->parent_name;
-		init.base = info->base;
-		init.sys_regs = data->sys_regs;
-		init.np = data->np;
-		init.flags = info->flags;
-		init.features = info->features;
-
-		data->plls[idx] = ccu_pll_hw_register(&init);
-		if (IS_ERR(data->plls[idx])) {
-			ret = PTR_ERR(data->plls[idx]);
-			pr_err("Couldn't register PLL hw '%s'\n",
-				init.name);
-			goto err_hw_unregister;
-		}
-	}
-
-	return 0;
-
-err_hw_unregister:
-	for (--idx; idx >= 0; --idx) {
-		if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer)
-			continue;
-
-		ccu_pll_hw_unregister(data->plls[idx]);
-	}
-
-	return ret;
-}
-
-static void ccu_pll_clk_unregister(struct ccu_pll_data *data, bool defer)
-{
-	int idx;
-
-	/* Uninstall only the clocks registered on the specified stage */
-	for (idx = 0; idx < CCU_PLL_NUM; ++idx) {
-		if (!!(pll_info[idx].features & CCU_PLL_BASIC) ^ defer)
-			continue;
-
-		ccu_pll_hw_unregister(data->plls[idx]);
-	}
-}
-
-static int ccu_pll_of_register(struct ccu_pll_data *data)
-{
-	int ret;
-
-	ret = of_clk_add_hw_provider(data->np, ccu_pll_of_clk_hw_get, data);
-	if (ret) {
-		pr_err("Couldn't register PLL provider of '%s'\n",
-			of_node_full_name(data->np));
-	}
-
-	return ret;
-}
-
-static int ccu_pll_probe(struct platform_device *pdev)
-{
-	struct ccu_pll_data *data = pll_data;
-
-	if (!data)
-		return -EINVAL;
-
-	return ccu_pll_clk_register(data, false);
-}
-
-static const struct of_device_id ccu_pll_of_match[] = {
-	{ .compatible = "baikal,bt1-ccu-pll" },
-	{ }
-};
-
-static struct platform_driver ccu_pll_driver = {
-	.probe  = ccu_pll_probe,
-	.driver = {
-		.name = "clk-ccu-pll",
-		.of_match_table = ccu_pll_of_match,
-		.suppress_bind_attrs = true,
-	},
-};
-builtin_platform_driver(ccu_pll_driver);
-
-static __init void ccu_pll_init(struct device_node *np)
-{
-	struct ccu_pll_data *data;
-	int ret;
-
-	data = ccu_pll_create_data(np);
-	if (IS_ERR(data))
-		return;
-
-	ret = ccu_pll_find_sys_regs(data);
-	if (ret)
-		goto err_free_data;
-
-	ret = ccu_pll_clk_register(data, true);
-	if (ret)
-		goto err_free_data;
-
-	ret = ccu_pll_of_register(data);
-	if (ret)
-		goto err_clk_unregister;
-
-	pll_data = data;
-
-	return;
-
-err_clk_unregister:
-	ccu_pll_clk_unregister(data, true);
-
-err_free_data:
-	ccu_pll_free_data(data);
-}
-CLK_OF_DECLARE_DRIVER(ccu_pll, "baikal,bt1-ccu-pll", ccu_pll_init);
diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c
index 1a9162f..df2d246 100644
--- a/drivers/clk/bcm/clk-raspberrypi.c
+++ b/drivers/clk/bcm/clk-raspberrypi.c
@@ -289,16 +289,31 @@ static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
 static int raspberrypi_fw_prepare(struct clk_hw *hw)
 {
 	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
+	struct raspberrypi_clk_variant *variant = data->variant;
 	struct raspberrypi_clk *rpi = data->rpi;
 	u32 state = RPI_FIRMWARE_STATE_ENABLE_BIT;
 	int ret;
 
 	ret = raspberrypi_clock_property(rpi->firmware, data,
 					 RPI_FIRMWARE_SET_CLOCK_STATE, &state);
-	if (ret)
+	if (ret) {
 		dev_err_ratelimited(rpi->dev,
 				    "Failed to set clock %s state to on: %d\n",
 				    clk_hw_get_name(hw), ret);
+		return ret;
+	}
+
+	/*
+	 * For clocks marked with 'maximize', restore the rate to the
+	 * maximum after enabling. This compensates for the rate being
+	 * set to minimum during unprepare (see raspberrypi_fw_unprepare).
+	 */
+	if (variant->maximize) {
+		unsigned long min_rate, max_rate;
+
+		clk_hw_get_rate_range(hw, &min_rate, &max_rate);
+		ret = raspberrypi_fw_set_rate(hw, max_rate, 0);
+	}
 
 	return ret;
 }
@@ -307,9 +322,27 @@ static void raspberrypi_fw_unprepare(struct clk_hw *hw)
 {
 	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
 	struct raspberrypi_clk *rpi = data->rpi;
+	unsigned long min_rate, max_rate;
 	u32 state = 0;
 	int ret;
 
+	clk_hw_get_rate_range(hw, &min_rate, &max_rate);
+
+	/*
+	 * Setting the rate in unprepare is a deviation from the usual CCF
+	 * behavior, where unprepare only gates the clock. However, this is
+	 * needed, as RPI_FIRMWARE_SET_CLOCK_STATE doesn't actually power off
+	 * the clock on current firmware versions. Setting the rate to minimum
+	 * before disabling the clock is the only way to achieve meaningful
+	 * power savings.
+	 *
+	 * This is safe because no consumer should rely on the rate of an
+	 * unprepared clock. Any consumer must call clk_prepare() before use,
+	 * at which point the rate is either restored to maximum (for clocks
+	 * with the 'maximize' flag) or re-established by the consumer.
+	 */
+	raspberrypi_fw_set_rate(hw, min_rate, 0);
+
 	ret = raspberrypi_clock_property(rpi->firmware, data,
 					 RPI_FIRMWARE_SET_CLOCK_STATE, &state);
 	if (ret)
@@ -387,9 +420,6 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
 		}
 	}
 
-	if (variant->maximize)
-		variant->min_rate = max_rate;
-
 	if (variant->min_rate) {
 		unsigned long rate;
 
diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 44d010b..835b1e4 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -47,22 +47,10 @@ static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw,
 						   struct clk_hw *parent_hw,
 						   const struct clk_ops *rate_ops)
 {
-	long rate;
-
 	req->best_parent_hw = parent_hw;
 	req->best_parent_rate = clk_hw_get_rate(parent_hw);
 
-	if (rate_ops->determine_rate)
-		return rate_ops->determine_rate(rate_hw, req);
-
-	rate = rate_ops->round_rate(rate_hw, req->rate,
-				    &req->best_parent_rate);
-	if (rate < 0)
-		return rate;
-
-	req->rate = rate;
-
-	return 0;
+	return rate_ops->determine_rate(rate_hw, req);
 }
 
 static int clk_composite_determine_rate(struct clk_hw *hw,
@@ -79,8 +67,7 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
 	unsigned long best_rate = 0;
 	int i, ret;
 
-	if (rate_hw && rate_ops &&
-	    (rate_ops->determine_rate || rate_ops->round_rate) &&
+	if (rate_hw && rate_ops && rate_ops->determine_rate &&
 	    mux_hw && mux_ops && mux_ops->set_parent) {
 		req->best_parent_hw = NULL;
 
@@ -150,18 +137,6 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
 	}
 }
 
-static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
-				  unsigned long *prate)
-{
-	struct clk_composite *composite = to_clk_composite(hw);
-	const struct clk_ops *rate_ops = composite->rate_ops;
-	struct clk_hw *rate_hw = composite->rate_hw;
-
-	__clk_hw_set_clk(rate_hw, hw);
-
-	return rate_ops->round_rate(rate_hw, rate, prate);
-}
-
 static int clk_composite_set_rate(struct clk_hw *hw, unsigned long rate,
 			       unsigned long parent_rate)
 {
@@ -288,17 +263,14 @@ static struct clk_hw *__clk_hw_register_composite(struct device *dev,
 		if (rate_ops->determine_rate)
 			clk_composite_ops->determine_rate =
 				clk_composite_determine_rate;
-		else if (rate_ops->round_rate)
-			clk_composite_ops->round_rate =
-				clk_composite_round_rate;
 
-		/* .set_rate requires either .round_rate or .determine_rate */
+		/* .set_rate requires .determine_rate */
 		if (rate_ops->set_rate) {
-			if (rate_ops->determine_rate || rate_ops->round_rate)
+			if (rate_ops->determine_rate)
 				clk_composite_ops->set_rate =
 						clk_composite_set_rate;
 			else
-				WARN(1, "%s: missing round_rate op is required\n",
+				WARN(1, "%s: missing determine_rate op is required\n",
 						__func__);
 		}
 
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 45e7ebd..b3b485d 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -387,50 +387,6 @@ int divider_ro_determine_rate(struct clk_hw *hw, struct clk_rate_request *req,
 }
 EXPORT_SYMBOL_GPL(divider_ro_determine_rate);
 
-long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
-			       unsigned long rate, unsigned long *prate,
-			       const struct clk_div_table *table,
-			       u8 width, unsigned long flags)
-{
-	struct clk_rate_request req;
-	int ret;
-
-	clk_hw_init_rate_request(hw, &req, rate);
-	req.best_parent_rate = *prate;
-	req.best_parent_hw = parent;
-
-	ret = divider_determine_rate(hw, &req, table, width, flags);
-	if (ret)
-		return ret;
-
-	*prate = req.best_parent_rate;
-
-	return req.rate;
-}
-EXPORT_SYMBOL_GPL(divider_round_rate_parent);
-
-long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
-				  unsigned long rate, unsigned long *prate,
-				  const struct clk_div_table *table, u8 width,
-				  unsigned long flags, unsigned int val)
-{
-	struct clk_rate_request req;
-	int ret;
-
-	clk_hw_init_rate_request(hw, &req, rate);
-	req.best_parent_rate = *prate;
-	req.best_parent_hw = parent;
-
-	ret = divider_ro_determine_rate(hw, &req, table, width, flags, val);
-	if (ret)
-		return ret;
-
-	*prate = req.best_parent_rate;
-
-	return req.rate;
-}
-EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);
-
 static int clk_divider_determine_rate(struct clk_hw *hw,
 				      struct clk_rate_request *req)
 {
diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c
index 08cc8e5..1ab0e2e 100644
--- a/drivers/clk/clk-en7523.c
+++ b/drivers/clk/clk-en7523.c
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/clk-provider.h>
 #include <linux/io.h>
@@ -11,6 +12,8 @@
 #include <dt-bindings/clock/en7523-clk.h>
 #include <dt-bindings/reset/airoha,en7523-reset.h>
 #include <dt-bindings/reset/airoha,en7581-reset.h>
+#include <dt-bindings/clock/econet,en751221-scu.h>
+#include <dt-bindings/reset/econet,en751221-scu.h>
 
 #define RST_NR_PER_BANK			32
 
@@ -33,15 +36,50 @@
 #define   REG_RESET_CONTROL_PCIEHB	BIT(29)
 #define   REG_RESET_CONTROL_PCIE1	BIT(27)
 #define   REG_RESET_CONTROL_PCIE2	BIT(26)
+#define REG_HIR				0x064
+#define   REG_HIR_MASK			GENMASK(31, 16)
 /* EN7581 */
 #define REG_NP_SCU_PCIC			0x88
 #define REG_NP_SCU_SSTR			0x9c
 #define REG_PCIE_XSI0_SEL_MASK		GENMASK(14, 13)
 #define REG_PCIE_XSI1_SEL_MASK		GENMASK(12, 11)
 #define REG_CRYPTO_CLKSRC2		0x20c
+/* EN751221 */
+#define EN751221_REG_SPI_DIV		0x0cc
+#define EN751221_REG_SPI_DIV_MASK	GENMASK(31, 8)
+#define EN751221_SPI_BASE		500000000
+#define EN751221_SPI_BASE_EN7526C	400000000
+#define EN751221_SPI_DIV_DEFAULT	40
+#define EN751221_REG_BUS		0x284
+#define EN751221_REG_BUS_MASK		GENMASK(21, 12)
+#define EN751221_REG_SSR3		0x094
+#define EN751221_REG_SSR3_GSW_MASK	GENMASK(9, 8)
 
 #define REG_RST_CTRL2			0x830
 #define REG_RST_CTRL1			0x834
+#define EN751221_REG_RST_DMT		0x84
+#define EN751221_REG_RST_USB		0xec
+
+#define EN751221_MAX_CLKS		5
+
+enum en_hir {
+	HIR_UNKNOWN	= -1,
+	HIR_TC3169	= 0,
+	HIR_TC3182	= 1,
+	HIR_RT65168	= 2,
+	HIR_RT63165	= 3,
+	HIR_RT63365	= 4,
+	HIR_MT751020	= 5,
+	HIR_MT7505	= 6,
+	HIR_EN751221	= 7,
+	HIR_EN7526C	= 8,
+	HIR_EN751627	= 9,
+	HIR_EN7580	= 10,
+	HIR_EN7528	= 11,
+	HIR_EN7523	= 12,
+	HIR_EN7581	= 13,
+	HIR_MAX		= 14,
+};
 
 struct en_clk_desc {
 	int id;
@@ -93,6 +131,8 @@ static const u32 bus7581_base[] = { 600000000, 540000000 };
 static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 };
 static const u32 crypto_base[] = { 540000000, 480000000 };
 static const u32 emmc7581_base[] = { 200000000, 150000000 };
+/* EN751221 */
+static const u32 gsw751221_base[] = { 500000000, 250000000, 400000000, 200000000 };
 
 static const struct en_clk_desc en7523_base_clks[] = {
 	{
@@ -300,6 +340,13 @@ static const u16 en7581_rst_ofs[] = {
 	REG_RST_CTRL1,
 };
 
+static const u16 en751221_rst_ofs[] = {
+	REG_RST_CTRL2,
+	REG_RST_CTRL1,
+	EN751221_REG_RST_DMT,
+	EN751221_REG_RST_USB,
+};
+
 static const u16 en7523_rst_map[] = {
 	/* RST_CTRL2 */
 	[EN7523_XPON_PHY_RST]		= 0,
@@ -405,8 +452,61 @@ static const u16 en7581_rst_map[] = {
 	[EN7581_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
 };
 
+static const u16 en751221_rst_map[] = {
+	/* RST_CTRL2 */
+	[EN751221_XPON_PHY_RST]		= 0,
+	[EN751221_GFAST_RST]		= 1,
+	[EN751221_CPU_TIMER2_RST]	= 2,
+	[EN751221_UART3_RST]		= 3,
+	[EN751221_UART4_RST]		= 4,
+	[EN751221_UART5_RST]		= 5,
+	[EN751221_I2C2_RST]		= 6,
+	[EN751221_XSI_MAC_RST]		= 7,
+	[EN751221_XSI_PHY_RST]		= 8,
+
+	/* RST_CTRL1 */
+	[EN751221_PCM1_ZSI_ISI_RST]	= RST_NR_PER_BANK + 0,
+	[EN751221_FE_QDMA1_RST]		= RST_NR_PER_BANK + 1,
+	[EN751221_FE_QDMA2_RST]		= RST_NR_PER_BANK + 2,
+	[EN751221_FE_UNZIP_RST]		= RST_NR_PER_BANK + 3,
+	[EN751221_PCM2_RST]		= RST_NR_PER_BANK + 4,
+	[EN751221_PTM_MAC_RST]		= RST_NR_PER_BANK + 5,
+	[EN751221_CRYPTO_RST]		= RST_NR_PER_BANK + 6,
+	[EN751221_SAR_RST]		= RST_NR_PER_BANK + 7,
+	[EN751221_TIMER_RST]		= RST_NR_PER_BANK + 8,
+	[EN751221_INTC_RST]		= RST_NR_PER_BANK + 9,
+	[EN751221_BONDING_RST]		= RST_NR_PER_BANK + 10,
+	[EN751221_PCM1_RST]		= RST_NR_PER_BANK + 11,
+	[EN751221_UART_RST]		= RST_NR_PER_BANK + 12,
+	[EN751221_GPIO_RST]		= RST_NR_PER_BANK + 13,
+	[EN751221_GDMA_RST]		= RST_NR_PER_BANK + 14,
+	[EN751221_I2C_MASTER_RST]	= RST_NR_PER_BANK + 16,
+	[EN751221_PCM2_ZSI_ISI_RST]	= RST_NR_PER_BANK + 17,
+	[EN751221_SFC_RST]		= RST_NR_PER_BANK + 18,
+	[EN751221_UART2_RST]		= RST_NR_PER_BANK + 19,
+	[EN751221_GDMP_RST]		= RST_NR_PER_BANK + 20,
+	[EN751221_FE_RST]		= RST_NR_PER_BANK + 21,
+	[EN751221_USB_HOST_P0_RST]	= RST_NR_PER_BANK + 22,
+	[EN751221_GSW_RST]		= RST_NR_PER_BANK + 23,
+	[EN751221_SFC2_PCM_RST]		= RST_NR_PER_BANK + 25,
+	[EN751221_PCIE0_RST]		= RST_NR_PER_BANK + 26,
+	[EN751221_PCIE1_RST]		= RST_NR_PER_BANK + 27,
+	[EN751221_CPU_TIMER_RST]	= RST_NR_PER_BANK + 28,
+	[EN751221_PCIE_HB_RST]		= RST_NR_PER_BANK + 29,
+	[EN751221_SIMIF_RST]		= RST_NR_PER_BANK + 30,
+	[EN751221_XPON_MAC_RST]		= RST_NR_PER_BANK + 31,
+
+	/* RST_DMT */
+	[EN751221_DMT_RST]		= 2 * RST_NR_PER_BANK + 0,
+
+	/* RST_USB */
+	[EN751221_USB_PHY_P0_RST]	= 3 * RST_NR_PER_BANK + 6,
+	[EN751221_USB_PHY_P1_RST]	= 3 * RST_NR_PER_BANK + 7,
+};
+
 static int en7581_reset_register(struct device *dev, void __iomem *base,
-				 const u16 *rst_map, int nr_resets);
+				 const u16 *rst_map, int nr_resets,
+				 const u16 *rst_reg_ofs);
 
 static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
 {
@@ -604,7 +704,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev,
 	en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
 
 	return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map,
-				     ARRAY_SIZE(en7523_rst_map));
+				     ARRAY_SIZE(en7523_rst_map),
+				     en7581_rst_ofs);
 }
 
 static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
@@ -705,7 +806,8 @@ static const struct reset_control_ops en7581_reset_ops = {
 };
 
 static int en7581_reset_register(struct device *dev, void __iomem *base,
-				 const u16 *rst_map, int nr_resets)
+				 const u16 *rst_map, int nr_resets,
+				 const u16 *rst_reg_ofs)
 {
 	struct en_rst_data *rst_data;
 
@@ -713,7 +815,7 @@ static int en7581_reset_register(struct device *dev, void __iomem *base,
 	if (!rst_data)
 		return -ENOMEM;
 
-	rst_data->bank_ofs = en7581_rst_ofs;
+	rst_data->bank_ofs = rst_reg_ofs;
 	rst_data->idx_map = rst_map;
 	rst_data->base = base;
 
@@ -752,7 +854,107 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
 	writel(val | 3, base + REG_NP_SCU_PCIC);
 
 	return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
-				     ARRAY_SIZE(en7581_rst_map));
+				     ARRAY_SIZE(en7581_rst_map),
+				     en7581_rst_ofs);
+}
+
+static enum en_hir get_hw_id(void __iomem *np_base)
+{
+	u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR));
+
+	if (val < HIR_MAX)
+		return (enum en_hir)val;
+
+	pr_warn("Unable to determine EcoNet SoC\n");
+
+	return HIR_UNKNOWN;
+}
+
+static void en751221_try_register_clk(struct device *dev, int key,
+				      struct clk_hw_onecell_data *clk_data,
+				      const char *name, u32 rate)
+{
+	struct clk_hw *hw;
+
+	if (WARN_ON_ONCE(key >= EN751221_MAX_CLKS))
+		return;
+
+	hw = clk_hw_register_fixed_rate(dev, name, NULL, 0, rate);
+	if (IS_ERR(hw))
+		pr_err("Failed to register clk %s: %pe\n", name, hw);
+	else
+		clk_data->hws[key] = hw;
+}
+
+static void en751221_register_clocks(struct device *dev,
+				     struct clk_hw_onecell_data *clk_data,
+				     struct regmap *map, void __iomem *np_base)
+{
+	enum en_hir hid = get_hw_id(np_base);
+	struct clk_hw *hw;
+	u32 rate;
+	u32 div;
+	int err;
+
+	/* PCI */
+	hw = en7523_register_pcie_clk(dev, np_base);
+	clk_data->hws[EN751221_CLK_PCIE] = hw;
+
+	/* SPI */
+	rate = EN751221_SPI_BASE;
+	if (hid == HIR_EN7526C)
+		rate = EN751221_SPI_BASE_EN7526C;
+
+	err = regmap_read(map, EN751221_REG_SPI_DIV, &div);
+	if (err) {
+		pr_err("Failed reading fixed clk div %s: %d\n",
+		       "spi", err);
+	} else {
+		div = FIELD_GET(EN751221_REG_SPI_DIV_MASK, div) * 2;
+		if (!div)
+			div = EN751221_SPI_DIV_DEFAULT;
+
+		en751221_try_register_clk(dev, EN751221_CLK_SPI, clk_data,
+					  "spi", rate / div);
+	}
+
+	/* BUS */
+	rate = FIELD_GET(EN751221_REG_BUS_MASK,
+			 readl(np_base + EN751221_REG_BUS));
+	rate *= 1000000;
+	en751221_try_register_clk(dev, EN751221_CLK_BUS, clk_data, "bus",
+				  rate);
+
+	/* CPU */
+	en751221_try_register_clk(dev, EN751221_CLK_CPU, clk_data, "cpu",
+				  rate * 4);
+
+	/* GSW */
+	rate = FIELD_GET(EN751221_REG_SSR3_GSW_MASK,
+			 readl(np_base + EN751221_REG_SSR3));
+	en751221_try_register_clk(dev, EN751221_CLK_GSW, clk_data, "gsw",
+				  gsw751221_base[rate]);
+}
+
+static int en751221_clk_hw_init(struct platform_device *pdev,
+				struct clk_hw_onecell_data *clk_data)
+{
+	struct regmap *map;
+	void __iomem *base;
+
+	map = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu");
+	if (IS_ERR(map))
+		return PTR_ERR(map);
+
+	base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(base))
+		return PTR_ERR(base);
+
+	en751221_register_clocks(&pdev->dev, clk_data, map, base);
+
+	return en7581_reset_register(&pdev->dev, base, en751221_rst_map,
+				     ARRAY_SIZE(en751221_rst_map),
+				     en751221_rst_ofs);
 }
 
 static int en7523_clk_probe(struct platform_device *pdev)
@@ -799,9 +1001,20 @@ static const struct en_clk_soc_data en7581_data = {
 	.hw_init = en7581_clk_hw_init,
 };
 
+static const struct en_clk_soc_data en751221_data = {
+	.num_clocks = EN751221_MAX_CLKS,
+	.pcie_ops = {
+		.is_enabled = en7523_pci_is_enabled,
+		.prepare = en7523_pci_prepare,
+		.unprepare = en7523_pci_unprepare,
+	},
+	.hw_init = en751221_clk_hw_init,
+};
+
 static const struct of_device_id of_match_clk_en7523[] = {
 	{ .compatible = "airoha,en7523-scu", .data = &en7523_data },
 	{ .compatible = "airoha,en7581-scu", .data = &en7581_data },
+	{ .compatible = "econet,en751221-scu", .data = &en751221_data },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
index cba45e0..eded6a5 100644
--- a/drivers/clk/clk-fsl-sai.c
+++ b/drivers/clk/clk-fsl-sai.c
@@ -5,34 +5,110 @@
  * Copyright 2020 Michael Walle <michael@walle.cc>
  */
 
-#include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/clk-provider.h>
+#include <linux/clk.h>
 #include <linux/err.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 
 #define I2S_CSR		0x00
 #define I2S_CR2		0x08
+#define I2S_MCR		0x100
 #define CSR_BCE_BIT	28
+#define CSR_TE_BIT	31
 #define CR2_BCD		BIT(24)
 #define CR2_DIV_SHIFT	0
 #define CR2_DIV_WIDTH	8
+#define MCR_MOE		BIT(30)
+
+struct fsl_sai_data {
+	unsigned int	offset;	/* Register offset */
+	bool		have_mclk; /* Have MCLK control */
+};
 
 struct fsl_sai_clk {
-	struct clk_divider div;
-	struct clk_gate gate;
+	const struct fsl_sai_data *data;
+	struct clk_divider bclk_div;
+	struct clk_divider mclk_div;
+	struct clk_gate bclk_gate;
+	struct clk_gate mclk_gate;
+	struct clk_hw *bclk_hw;
+	struct clk_hw *mclk_hw;
 	spinlock_t lock;
 };
 
+static struct clk_hw *
+fsl_sai_of_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct fsl_sai_clk *sai_clk = data;
+
+	if (clkspec->args_count == 0)
+		return sai_clk->bclk_hw;
+
+	if (clkspec->args_count == 1) {
+		if (clkspec->args[0] == 0)
+			return sai_clk->bclk_hw;
+		if (sai_clk->data->have_mclk && clkspec->args[0] == 1)
+			return sai_clk->mclk_hw;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int fsl_sai_clk_register(struct device *dev, void __iomem *base,
+				spinlock_t *lock, struct clk_divider *div,
+				struct clk_gate *gate, struct clk_hw **hw,
+				const int gate_bit, const int dir_bit,
+				const int div_reg, char *name)
+{
+	const struct fsl_sai_data *data = device_get_match_data(dev);
+	struct clk_parent_data pdata = { .index = 0 };
+	struct clk_hw *chw;
+	char *cname;
+
+	gate->reg = base + data->offset + I2S_CSR;
+	gate->bit_idx = gate_bit;
+	gate->lock = lock;
+
+	div->reg = base + div_reg;
+	div->shift = CR2_DIV_SHIFT;
+	div->width = CR2_DIV_WIDTH;
+	div->lock = lock;
+
+	cname = devm_kasprintf(dev, GFP_KERNEL, "%s.%s",
+			       of_node_full_name(dev->of_node), name);
+	if (!cname)
+		return -ENOMEM;
+
+	/* Set clock direction */
+	writel(dir_bit, base + div_reg);
+
+	chw = devm_clk_hw_register_composite_pdata(dev, cname,
+						   &pdata, 1, NULL, NULL,
+						   &div->hw,
+						   &clk_divider_ops,
+						   &gate->hw,
+						   &clk_gate_ops,
+						   CLK_SET_RATE_GATE);
+	if (IS_ERR(chw))
+		return PTR_ERR(chw);
+
+	*hw = chw;
+
+	return 0;
+}
+
 static int fsl_sai_clk_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
+	const struct fsl_sai_data *data = device_get_match_data(dev);
 	struct fsl_sai_clk *sai_clk;
-	struct clk_parent_data pdata = { .index = 0 };
+	struct clk *clk_bus;
 	void __iomem *base;
-	struct clk_hw *hw;
+	int ret;
 
 	sai_clk = devm_kzalloc(dev, sizeof(*sai_clk), GFP_KERNEL);
 	if (!sai_clk)
@@ -42,35 +118,47 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
 	if (IS_ERR(base))
 		return PTR_ERR(base);
 
+	clk_bus = devm_clk_get_optional_enabled(dev, "bus");
+	if (IS_ERR(clk_bus))
+		return PTR_ERR(clk_bus);
+
+	sai_clk->data = data;
 	spin_lock_init(&sai_clk->lock);
 
-	sai_clk->gate.reg = base + I2S_CSR;
-	sai_clk->gate.bit_idx = CSR_BCE_BIT;
-	sai_clk->gate.lock = &sai_clk->lock;
+	ret = fsl_sai_clk_register(dev, base, &sai_clk->lock,
+				   &sai_clk->bclk_div, &sai_clk->bclk_gate,
+				   &sai_clk->bclk_hw, CSR_BCE_BIT, CR2_BCD,
+				   data->offset + I2S_CR2, "BCLK");
+	if (ret)
+		return ret;
 
-	sai_clk->div.reg = base + I2S_CR2;
-	sai_clk->div.shift = CR2_DIV_SHIFT;
-	sai_clk->div.width = CR2_DIV_WIDTH;
-	sai_clk->div.lock = &sai_clk->lock;
+	if (data->have_mclk) {
+		ret = fsl_sai_clk_register(dev, base, &sai_clk->lock,
+					   &sai_clk->mclk_div,
+					   &sai_clk->mclk_gate,
+					   &sai_clk->mclk_hw,
+					   CSR_TE_BIT, MCR_MOE, I2S_MCR,
+					   "MCLK");
+		if (ret)
+			return ret;
+	}
 
-	/* set clock direction, we are the BCLK master */
-	writel(CR2_BCD, base + I2S_CR2);
-
-	hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name,
-						  &pdata, 1, NULL, NULL,
-						  &sai_clk->div.hw,
-						  &clk_divider_ops,
-						  &sai_clk->gate.hw,
-						  &clk_gate_ops,
-						  CLK_SET_RATE_GATE);
-	if (IS_ERR(hw))
-		return PTR_ERR(hw);
-
-	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
+	return devm_of_clk_add_hw_provider(dev, fsl_sai_of_clk_get, sai_clk);
 }
 
+static const struct fsl_sai_data fsl_sai_vf610_data = {
+	.offset	= 0,
+	.have_mclk = false,
+};
+
+static const struct fsl_sai_data fsl_sai_imx8mq_data = {
+	.offset	= 8,
+	.have_mclk = true,
+};
+
 static const struct of_device_id of_fsl_sai_clk_ids[] = {
-	{ .compatible = "fsl,vf610-sai-clock" },
+	{ .compatible = "fsl,vf610-sai-clock", .data = &fsl_sai_vf610_data },
+	{ .compatible = "fsl,imx8mq-sai-clock", .data = &fsl_sai_imx8mq_data },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids);
diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
index f05631e5..2524c5c 100644
--- a/drivers/clk/clk-qoriq.c
+++ b/drivers/clk/clk-qoriq.c
@@ -907,13 +907,11 @@ static const struct clockgen_pll_div *get_pll_div(struct clockgen *cg,
 	return &cg->pll[pll].div[div];
 }
 
-static struct clk * __init create_mux_common(struct clockgen *cg,
-					     struct mux_hwclock *hwc,
-					     const struct clk_ops *ops,
-					     unsigned long min_rate,
-					     unsigned long max_rate,
-					     unsigned long pct80_rate,
-					     const char *fmt, int idx)
+static struct clk * __init __printf(7, 8)
+create_mux_common(struct clockgen *cg, struct mux_hwclock *hwc,
+		  const struct clk_ops *ops, unsigned long min_rate,
+		  unsigned long max_rate, unsigned long pct80_rate,
+		  const char *fmt, ...)
 {
 	struct clk_init_data init = {};
 	struct clk *clk;
@@ -921,8 +919,11 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
 	const char *parent_names[NUM_MUX_PARENTS];
 	char name[32];
 	int i, j;
+	va_list args;
 
-	snprintf(name, sizeof(name), fmt, idx);
+	va_start(args, fmt);
+	vsnprintf(name, sizeof(name), fmt, args);
+	va_end(args);
 
 	for (i = 0, j = 0; i < NUM_MUX_PARENTS; i++) {
 		unsigned long rate;
diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c
index ba3b105..abb6c8f 100644
--- a/drivers/clk/clk-xgene.c
+++ b/drivers/clk/clk-xgene.c
@@ -188,6 +188,8 @@ static void xgene_pllclk_init(struct device_node *np, enum xgene_pll_type pll_ty
 		of_clk_add_provider(np, of_clk_src_simple_get, clk);
 		clk_register_clkdev(clk, clk_name, NULL);
 		pr_debug("Add %s clock PLL\n", clk_name);
+	} else {
+		iounmap(reg);
 	}
 }
 
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 47093cd..048adfa 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -1560,8 +1560,6 @@ late_initcall_sync(clk_disable_unused);
 static int clk_core_determine_round_nolock(struct clk_core *core,
 					   struct clk_rate_request *req)
 {
-	long rate;
-
 	lockdep_assert_held(&prepare_lock);
 
 	if (!core)
@@ -1591,13 +1589,6 @@ static int clk_core_determine_round_nolock(struct clk_core *core,
 		req->rate = core->rate;
 	} else if (core->ops->determine_rate) {
 		return core->ops->determine_rate(core->hw, req);
-	} else if (core->ops->round_rate) {
-		rate = core->ops->round_rate(core->hw, req->rate,
-					     &req->best_parent_rate);
-		if (rate < 0)
-			return rate;
-
-		req->rate = rate;
 	} else {
 		return -EINVAL;
 	}
@@ -1682,7 +1673,7 @@ EXPORT_SYMBOL_GPL(clk_hw_forward_rate_request);
 
 static bool clk_core_can_round(struct clk_core * const core)
 {
-	return core->ops->determine_rate || core->ops->round_rate;
+	return core->ops->determine_rate;
 }
 
 static int clk_core_round_rate_nolock(struct clk_core *core,
@@ -1750,11 +1741,11 @@ EXPORT_SYMBOL_GPL(__clk_determine_rate);
  * use.
  *
  * Context: prepare_lock must be held.
- *          For clk providers to call from within clk_ops such as .round_rate,
+ *          For clk providers to call from within clk_ops such as
  *          .determine_rate.
  *
- * Return: returns rounded rate of hw clk if clk supports round_rate operation
- *         else returns the parent rate.
+ * Return: returns rounded rate of hw clk if clk supports determine_rate
+ *         operation; else returns the parent rate.
  */
 unsigned long clk_hw_round_rate(struct clk_hw *hw, unsigned long rate)
 {
@@ -2569,12 +2560,13 @@ static int clk_core_set_rate_nolock(struct clk_core *core,
  *
  * Setting the CLK_SET_RATE_PARENT flag allows the rate change operation to
  * propagate up to clk's parent; whether or not this happens depends on the
- * outcome of clk's .round_rate implementation.  If *parent_rate is unchanged
- * after calling .round_rate then upstream parent propagation is ignored.  If
- * *parent_rate comes back with a new rate for clk's parent then we propagate
- * up to clk's parent and set its rate.  Upward propagation will continue
- * until either a clk does not support the CLK_SET_RATE_PARENT flag or
- * .round_rate stops requesting changes to clk's parent_rate.
+ * outcome of clk's .determine_rate implementation. If req->best_parent_rate
+ * is unchanged after calling .determine_rate then upstream parent propagation
+ * is ignored.  If req->best_parent_rate comes back with a new rate for clk's
+ * parent then we propagate up to clk's parent and set its rate. Upward
+ * propagation will continue until either a clk does not support the
+ * CLK_SET_RATE_PARENT flag or .determine_rate stops requesting changes to
+ * clk's parent_rate.
  *
  * Rate changes are accomplished via tree traversal that also recalculates the
  * rates for the clocks and fires off POST_RATE_CHANGE notifiers.
@@ -2703,8 +2695,6 @@ static int clk_set_rate_range_nolock(struct clk *clk,
 	 * FIXME:
 	 * There is a catch. It may fail for the usual reason (clock
 	 * broken, clock protected, etc) but also because:
-	 * - round_rate() was not favorable and fell on the wrong
-	 *   side of the boundary
 	 * - the determine_rate() callback does not really check for
 	 *   this corner case when determining the rate
 	 */
@@ -3259,11 +3249,10 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
 		return true;
 
 	/* true if clk->core pointers match. Avoid dereferencing garbage */
-	if (!IS_ERR_OR_NULL(p) && !IS_ERR_OR_NULL(q))
-		if (p->core == q->core)
-			return true;
+	if (IS_ERR_OR_NULL(p) || IS_ERR_OR_NULL(q))
+		return false;
 
-	return false;
+	return p->core == q->core;
 }
 EXPORT_SYMBOL_GPL(clk_is_match);
 
@@ -3915,10 +3904,9 @@ static int __clk_core_init(struct clk_core *core)
 	}
 
 	/* check that clk_ops are sane.  See Documentation/driver-api/clk.rst */
-	if (core->ops->set_rate &&
-	    !((core->ops->round_rate || core->ops->determine_rate) &&
-	      core->ops->recalc_rate)) {
-		pr_err("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
+	if (core->ops->set_rate && !core->ops->determine_rate &&
+	      core->ops->recalc_rate) {
+		pr_err("%s: %s must implement .determine_rate in addition to .recalc_rate\n",
 		       __func__, core->name);
 		ret = -EINVAL;
 		goto out;
diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c
index a268d7b..b1961da 100644
--- a/drivers/clk/clk_test.c
+++ b/drivers/clk/clk_test.c
@@ -241,8 +241,8 @@ static void clk_test_get_rate(struct kunit *test)
  * Test that, after a call to clk_set_rate(), the rate returned by
  * clk_get_rate() matches.
  *
- * This assumes that clk_ops.determine_rate or clk_ops.round_rate won't
- * modify the requested rate, which is our case in clk_dummy_rate_ops.
+ * This assumes that clk_ops.determine_rate won't modify the requested rate,
+ * which is our case in clk_dummy_rate_ops.
  */
 static void clk_test_set_get_rate(struct kunit *test)
 {
@@ -266,8 +266,8 @@ static void clk_test_set_get_rate(struct kunit *test)
  * Test that, after several calls to clk_set_rate(), the rate returned
  * by clk_get_rate() matches the last one.
  *
- * This assumes that clk_ops.determine_rate or clk_ops.round_rate won't
- * modify the requested rate, which is our case in clk_dummy_rate_ops.
+ * This assumes that clk_ops.determine_rate won't modify the requested rate,
+ * which is our case in clk_dummy_rate_ops.
  */
 static void clk_test_set_set_get_rate(struct kunit *test)
 {
@@ -1675,8 +1675,8 @@ static void clk_range_test_set_range_set_round_rate_consistent_higher(struct kun
  * call to clk_set_rate_range(), the rate will be raised to match the
  * new minimum.
  *
- * This assumes that clk_ops.determine_rate or clk_ops.round_rate won't
- * modify the requested rate, which is our case in clk_dummy_rate_ops.
+ * This assumes that clk_ops.determine_rate won't modify the requested rate,
+ * which is our case in clk_dummy_rate_ops.
  */
 static void clk_range_test_set_range_get_rate_raised(struct kunit *test)
 {
@@ -1707,8 +1707,8 @@ static void clk_range_test_set_range_get_rate_raised(struct kunit *test)
  * call to clk_set_rate_range(), the rate will be lowered to match the
  * new maximum.
  *
- * This assumes that clk_ops.determine_rate or clk_ops.round_rate won't
- * modify the requested rate, which is our case in clk_dummy_rate_ops.
+ * This assumes that clk_ops.determine_rate won't modify the requested rate,
+ * which is our case in clk_dummy_rate_ops.
  */
 static void clk_range_test_set_range_get_rate_lowered(struct kunit *test)
 {
diff --git a/drivers/clk/eswin/Kconfig b/drivers/clk/eswin/Kconfig
new file mode 100644
index 0000000..0406ec4
--- /dev/null
+++ b/drivers/clk/eswin/Kconfig
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config COMMON_CLK_ESWIN
+	bool
+
+config COMMON_CLK_EIC7700
+	tristate "EIC7700 Clock Driver"
+	depends on ARCH_ESWIN || COMPILE_TEST
+	select COMMON_CLK_ESWIN
+	default ARCH_ESWIN
+	help
+	  This driver provides support for clock controller on ESWIN EIC7700
+	  SoC. The clock controller generates and supplies clocks to various
+	  peripherals within the SoC.
+	  Say yes here to support the clock controller on the EIC7700 SoC.
diff --git a/drivers/clk/eswin/Makefile b/drivers/clk/eswin/Makefile
new file mode 100644
index 0000000..4a7c2af
--- /dev/null
+++ b/drivers/clk/eswin/Makefile
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Eswin Clock specific Makefile
+#
+
+obj-$(CONFIG_COMMON_CLK_ESWIN)		+= clk.o
+
+obj-$(CONFIG_COMMON_CLK_EIC7700)	+= clk-eic7700.o
diff --git a/drivers/clk/eswin/clk-eic7700.c b/drivers/clk/eswin/clk-eic7700.c
new file mode 100644
index 0000000..be81d74
--- /dev/null
+++ b/drivers/clk/eswin/clk-eic7700.c
@@ -0,0 +1,1376 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
+ * All rights reserved.
+ *
+ * ESWIN EIC7700 Clk Provider Driver
+ *
+ * Authors:
+ *	Yifeng Huang <huangyifeng@eswincomputing.com>
+ *	Xuyang Dong <dongxuyang@eswincomputing.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/clock/eswin,eic7700-clock.h>
+
+#include "common.h"
+
+/* REG OFFSET OF SYS-CRG */
+#define EIC7700_REG_OFFSET_SPLL0_CFG_0		0x0
+#define EIC7700_REG_OFFSET_SPLL0_CFG_1		0x4
+#define EIC7700_REG_OFFSET_SPLL0_CFG_2		0x8
+#define EIC7700_REG_OFFSET_SPLL0_DSKEWCAL	0xC
+#define EIC7700_REG_OFFSET_SPLL0_SSC		0x10
+#define EIC7700_REG_OFFSET_SPLL1_CFG_0		0x14
+#define EIC7700_REG_OFFSET_SPLL1_CFG_1		0x18
+#define EIC7700_REG_OFFSET_SPLL1_CFG_2		0x1C
+#define EIC7700_REG_OFFSET_SPLL1_DSKEWCAL	0x20
+#define EIC7700_REG_OFFSET_SPLL1_SSC		0x24
+#define EIC7700_REG_OFFSET_SPLL2_CFG_0		0x28
+#define EIC7700_REG_OFFSET_SPLL2_CFG_1		0x2C
+#define EIC7700_REG_OFFSET_SPLL2_CFG_2		0x30
+#define EIC7700_REG_OFFSET_SPLL2_DSKEWCAL	0x34
+#define EIC7700_REG_OFFSET_SPLL2_SSC		0x38
+#define EIC7700_REG_OFFSET_VPLL_CFG_0		0x3C
+#define EIC7700_REG_OFFSET_VPLL_CFG_1		0x40
+#define EIC7700_REG_OFFSET_VPLL_CFG_2		0x44
+#define EIC7700_REG_OFFSET_VPLL_DSKEWCAL	0x48
+#define EIC7700_REG_OFFSET_VPLL_SSC		0x4C
+#define EIC7700_REG_OFFSET_APLL_CFG_0		0x50
+#define EIC7700_REG_OFFSET_APLL_CFG_1		0x54
+#define EIC7700_REG_OFFSET_APLL_CFG_2		0x58
+#define EIC7700_REG_OFFSET_APLL_DSKEWCAL	0x5C
+#define EIC7700_REG_OFFSET_APLL_SSC		0x60
+#define EIC7700_REG_OFFSET_MCPUT_PLL_CFG_0	0x64
+#define EIC7700_REG_OFFSET_MCPUT_PLL_CFG_1	0x68
+#define EIC7700_REG_OFFSET_MCPUT_PLL_CFG_2	0x6C
+#define EIC7700_REG_OFFSET_MCPUT_PLL_DSKEWCAL	0x70
+#define EIC7700_REG_OFFSET_MCPUT_PLL_SSC	0x74
+#define EIC7700_REG_OFFSET_DDRT_PLL_CFG_0	0x78
+#define EIC7700_REG_OFFSET_DDRT_PLL_CFG_1	0x7C
+#define EIC7700_REG_OFFSET_DDRT_PLL_CFG_2	0x80
+#define EIC7700_REG_OFFSET_DDRT_PLL_DSKEWCAL	0x84
+#define EIC7700_REG_OFFSET_DDRT_PLL_SSC		0x88
+#define EIC7700_REG_OFFSET_PLL_STATUS		0xA4
+#define EIC7700_REG_OFFSET_NOC			0x100
+#define EIC7700_REG_OFFSET_BOOTSPI		0x104
+#define EIC7700_REG_OFFSET_BOOTSPI_CFGCLK	0x108
+#define EIC7700_REG_OFFSET_SCPU_CORE		0x10C
+#define EIC7700_REG_OFFSET_SCPU_BUSCLK		0x110
+#define EIC7700_REG_OFFSET_LPCPU_CORE		0x114
+#define EIC7700_REG_OFFSET_LPCPU_BUSCLK		0x118
+#define EIC7700_REG_OFFSET_TCU_ACLK		0x11C
+#define EIC7700_REG_OFFSET_TCU_CFG		0x120
+#define EIC7700_REG_OFFSET_DDR			0x124
+#define EIC7700_REG_OFFSET_DDR1			0x128
+#define EIC7700_REG_OFFSET_GPU_ACLK		0x12C
+#define EIC7700_REG_OFFSET_GPU_CFG		0x130
+#define EIC7700_REG_OFFSET_GPU_GRAY		0x134
+#define EIC7700_REG_OFFSET_DSP_ACLK		0x138
+#define EIC7700_REG_OFFSET_DSP_CFG		0x13C
+#define EIC7700_REG_OFFSET_D2D_ACLK		0x140
+#define EIC7700_REG_OFFSET_D2D_CFG		0x144
+#define EIC7700_REG_OFFSET_HSP_ACLK		0x148
+#define EIC7700_REG_OFFSET_HSP_CFG		0x14C
+#define EIC7700_REG_OFFSET_SATA_RBC		0x150
+#define EIC7700_REG_OFFSET_SATA_OOB		0x154
+#define EIC7700_REG_OFFSET_ETH0			0x158
+#define EIC7700_REG_OFFSET_ETH1			0x15C
+#define EIC7700_REG_OFFSET_MSHC0_CORE		0x160
+#define EIC7700_REG_OFFSET_MSHC1_CORE		0x164
+#define EIC7700_REG_OFFSET_MSHC2_CORE		0x168
+#define EIC7700_REG_OFFSET_MSHC_USB_SLWCLK	0x16C
+#define EIC7700_REG_OFFSET_PCIE_ACLK		0x170
+#define EIC7700_REG_OFFSET_PCIE_CFG		0x174
+#define EIC7700_REG_OFFSET_NPU_ACLK		0x178
+#define EIC7700_REG_OFFSET_NPU_LLC		0x17C
+#define EIC7700_REG_OFFSET_NPU_CORE		0x180
+#define EIC7700_REG_OFFSET_VI_DWCLK		0x184
+#define EIC7700_REG_OFFSET_VI_ACLK		0x188
+#define EIC7700_REG_OFFSET_VI_DIG_ISP		0x18C
+#define EIC7700_REG_OFFSET_VI_DVP		0x190
+#define EIC7700_REG_OFFSET_VI_SHUTTER0		0x194
+#define EIC7700_REG_OFFSET_VI_SHUTTER1		0x198
+#define EIC7700_REG_OFFSET_VI_SHUTTER2		0x19C
+#define EIC7700_REG_OFFSET_VI_SHUTTER3		0x1A0
+#define EIC7700_REG_OFFSET_VI_SHUTTER4		0x1A4
+#define EIC7700_REG_OFFSET_VI_SHUTTER5		0x1A8
+#define EIC7700_REG_OFFSET_VI_PHY		0x1AC
+#define EIC7700_REG_OFFSET_VO_ACLK		0x1B0
+#define EIC7700_REG_OFFSET_VO_IESMCLK		0x1B4
+#define EIC7700_REG_OFFSET_VO_PIXEL		0x1B8
+#define EIC7700_REG_OFFSET_VO_MCLK		0x1BC
+#define EIC7700_REG_OFFSET_VO_PHY_CLK		0x1C0
+#define EIC7700_REG_OFFSET_VC_ACLK		0x1C4
+#define EIC7700_REG_OFFSET_VCDEC_ROOT		0x1C8
+#define EIC7700_REG_OFFSET_G2D			0x1CC
+#define EIC7700_REG_OFFSET_VC_CLKEN		0x1D0
+#define EIC7700_REG_OFFSET_JE			0x1D4
+#define EIC7700_REG_OFFSET_JD			0x1D8
+#define EIC7700_REG_OFFSET_VD			0x1DC
+#define EIC7700_REG_OFFSET_VE			0x1E0
+#define EIC7700_REG_OFFSET_AON_DMA		0x1E4
+#define EIC7700_REG_OFFSET_TIMER		0x1E8
+#define EIC7700_REG_OFFSET_RTC			0x1EC
+#define EIC7700_REG_OFFSET_PKA			0x1F0
+#define EIC7700_REG_OFFSET_SPACC		0x1F4
+#define EIC7700_REG_OFFSET_TRNG			0x1F8
+#define EIC7700_REG_OFFSET_OTP			0x1FC
+#define EIC7700_REG_OFFSET_LSP_EN0		0x200
+#define EIC7700_REG_OFFSET_LSP_EN1		0x204
+#define EIC7700_REG_OFFSET_U84			0x208
+#define EIC7700_REG_OFFSET_SYSCFG		0x20C
+#define EIC7700_REG_OFFSET_I2C0			0x210
+#define EIC7700_REG_OFFSET_I2C1			0x214
+
+#define EIC7700_NR_CLKS				(EIC7700_CLK_GATE_NOC_WDREF + 1)
+
+/*
+ * The 24 MHz oscillator, the root of most of the clock tree.
+ */
+static const struct clk_parent_data xtal24M[] = {
+	{ .index = 0, }
+};
+
+/* fixed rate clocks */
+static struct eswin_fixed_rate_clock eic7700_fixed_rate_clks[] = {
+	ESWIN_FIXED(EIC7700_CLK_XTAL_32K, "fixed_rate_clk_xtal_32k", 0, 32768),
+	ESWIN_FIXED(EIC7700_CLK_SPLL0_FOUT1, "fixed_rate_clk_spll0_fout1", 0,
+		    1600000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL0_FOUT2, "fixed_rate_clk_spll0_fout2", 0,
+		    800000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL0_FOUT3, "fixed_rate_clk_spll0_fout3", 0,
+		    400000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL1_FOUT1, "fixed_rate_clk_spll1_fout1", 0,
+		    1500000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL1_FOUT2, "fixed_rate_clk_spll1_fout2", 0,
+		    300000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL1_FOUT3, "fixed_rate_clk_spll1_fout3", 0,
+		    250000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL2_FOUT1, "fixed_rate_clk_spll2_fout1", 0,
+		    2080000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL2_FOUT2, "fixed_rate_clk_spll2_fout2", 0,
+		    1040000000),
+	ESWIN_FIXED(EIC7700_CLK_SPLL2_FOUT3, "fixed_rate_clk_spll2_fout3", 0,
+		    416000000),
+	ESWIN_FIXED(EIC7700_CLK_VPLL_FOUT1, "fixed_rate_clk_vpll_fout1", 0,
+		    1188000000),
+	ESWIN_FIXED(EIC7700_CLK_VPLL_FOUT2, "fixed_rate_clk_vpll_fout2", 0,
+		    594000000),
+	ESWIN_FIXED(EIC7700_CLK_VPLL_FOUT3, "fixed_rate_clk_vpll_fout3", 0,
+		    49500000),
+	ESWIN_FIXED(EIC7700_CLK_APLL_FOUT2, "fixed_rate_clk_apll_fout2", 0, 0),
+	ESWIN_FIXED(EIC7700_CLK_APLL_FOUT3, "fixed_rate_clk_apll_fout3", 0, 0),
+	ESWIN_FIXED(EIC7700_CLK_EXT_MCLK, "fixed_rate_ext_mclk", 0, 0),
+	ESWIN_FIXED(EIC7700_CLK_LPDDR_REF_BAK, "fixed_rate_lpddr_ref_bak", 0,
+		    50000000),
+};
+
+/* pll clocks */
+static struct eswin_pll_clock eic7700_pll_clks[] = {
+	ESWIN_PLL(EIC7700_CLK_APLL_FOUT1, "clk_apll_fout1", xtal24M,
+		  EIC7700_REG_OFFSET_APLL_CFG_0, 20,
+		  EIC7700_REG_OFFSET_APLL_CFG_1, 4,
+		  EIC7700_REG_OFFSET_APLL_CFG_2, EIC7700_REG_OFFSET_PLL_STATUS,
+		  4, 1, APLL_HIGH_FREQ, APLL_LOW_FREQ),
+	ESWIN_PLL(EIC7700_CLK_PLL_CPU, "clk_pll_cpu", xtal24M,
+		  EIC7700_REG_OFFSET_MCPUT_PLL_CFG_0, 20,
+		  EIC7700_REG_OFFSET_MCPUT_PLL_CFG_1, 4,
+		  EIC7700_REG_OFFSET_MCPUT_PLL_CFG_2,
+		  EIC7700_REG_OFFSET_PLL_STATUS, 5, 1, PLL_HIGH_FREQ,
+		  PLL_LOW_FREQ),
+};
+
+/* fixed factor clocks */
+static struct eswin_fixed_factor_clock eic7700_factor_clks[] = {
+	ESWIN_FACTOR(EIC7700_CLK_FIXED_FACTOR_CLK_1M_DIV24,
+		     "fixed_factor_clk_1m_div24", xtal24M, 1, 24, 0),
+	ESWIN_FACTOR(EIC7700_CLK_FIXED_FACTOR_PVT_DIV20,
+		     "fixed_factor_pvt_div20", xtal24M, 1, 20, 0),
+};
+
+/* divider clocks */
+static struct eswin_divider_clock eic7700_div_clks[] = {
+	ESWIN_DIV(EIC7700_CLK_DIV_U84_RTC_TOGGLE_DYNM,
+		  "divider_u84_rtc_toggle_dynm", xtal24M, 0,
+		  EIC7700_REG_OFFSET_RTC, 16, 5,
+		  CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV(EIC7700_CLK_DIV_NOC_WDREF_DYNM, "divider_noc_wdref_dynm",
+		  xtal24M, 0, EIC7700_REG_OFFSET_NOC, 4, 16,
+		  CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+};
+
+/* gate clocks */
+static struct eswin_gate_clock eic7700_gate_clks[] = {
+	ESWIN_GATE(EIC7700_CLK_GATE_GPU_GRAY_CLK, "gate_gpu_gray_clk", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_GPU_GRAY, 31, 0),
+	ESWIN_GATE(EIC7700_CLK_GATE_VI_PHY_CFG, "gate_vi_phy_cfg", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_PHY, 1, 0),
+	ESWIN_GATE(EIC7700_CLK_GATE_TIMER_CLK_0, "gate_time_clk_0", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 0, 0),
+	ESWIN_GATE(EIC7700_CLK_GATE_TIMER_CLK_1, "gate_time_clk_1", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 1, 0),
+	ESWIN_GATE(EIC7700_CLK_GATE_TIMER_CLK_2, "gate_time_clk_2", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 2, 0),
+	ESWIN_GATE(EIC7700_CLK_GATE_TIMER_CLK_3, "gate_time_clk_3", xtal24M,
+		   CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 3, 0),
+};
+
+/* Define the early clocks as the parent clocks of the mux clocks. */
+static struct eswin_clk_info eic7700_early_clks[] = {
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_HSP_RMII_REF_DIV6,
+			  "fixed_factor_hsp_rmii_ref_div6",
+			  EIC7700_CLK_SPLL1_FOUT2, 1, 6, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NPU_LLC_SRC0_DYNM,
+		       "divider_npu_llc_src0_div_dynm",
+		       EIC7700_CLK_SPLL0_FOUT1, 0, EIC7700_REG_OFFSET_NPU_LLC,
+		       4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NPU_LLC_SRC1_DYNM,
+		       "divider_npu_llc_src1_div_dynm",
+		       EIC7700_CLK_SPLL2_FOUT1, 0, EIC7700_REG_OFFSET_NPU_LLC,
+		       8, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_SPLL0_FOUT2, "gate_clk_spll0_fout2",
+			EIC7700_CLK_SPLL0_FOUT2,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_SPLL0_CFG_2, 31, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_BOOTSPI_DYNM, "divider_bootspi_div_dynm",
+		       EIC7700_CLK_GATE_SPLL0_FOUT2, 0,
+		       EIC7700_REG_OFFSET_BOOTSPI, 4, 6, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_SCPU_CORE_DYNM,
+		       "divider_scpu_core_div_dynm", EIC7700_CLK_SPLL0_FOUT1, 0,
+		       EIC7700_REG_OFFSET_SCPU_CORE, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_LPCPU_CORE_DYNM,
+		       "divider_lpcpu_core_div_dynm", EIC7700_CLK_SPLL0_FOUT1,
+		       0, EIC7700_REG_OFFSET_LPCPU_CORE, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VO_MCLK_DYNM, "divider_vo_mclk_div_dynm",
+		       EIC7700_CLK_APLL_FOUT1, 0, EIC7700_REG_OFFSET_VO_MCLK, 4,
+		       8, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_AONDMA_AXI_DYNM,
+		       "divider_aondma_axi_div_dynm", EIC7700_CLK_SPLL0_FOUT1,
+		       0, EIC7700_REG_OFFSET_AON_DMA, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_SATA_PHY_REF_DYNM,
+		       "divider_sata_phy_ref_div_dynm",
+		       EIC7700_CLK_SPLL1_FOUT2, 0, EIC7700_REG_OFFSET_SATA_OOB,
+		       0, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_SYS_CFG_DYNM, "divider_sys_cfg_div_dynm",
+		       EIC7700_CLK_SPLL0_FOUT3, 0, EIC7700_REG_OFFSET_SYSCFG, 4,
+		       3, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_U84_CORE_LP_DIV2,
+			  "fixed_factor_u84_core_lp_div2",
+			  EIC7700_CLK_GATE_SPLL0_FOUT2, 1, 2, 0),
+};
+
+static const struct clk_parent_data dsp_aclk_root_2mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data d2d_aclk_root_2mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data ddr_aclk_root_2mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data mshcore_root_3mux1_0_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[3].hw },
+	{ .hw = &eic7700_fixed_rate_clks[9].hw },
+};
+
+static const struct clk_parent_data mshcore_root_3mux1_1_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[3].hw },
+	{ .hw = &eic7700_fixed_rate_clks[9].hw },
+};
+
+static const struct clk_parent_data mshcore_root_3mux1_2_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[3].hw },
+	{ .hw = &eic7700_fixed_rate_clks[9].hw },
+};
+
+static const struct clk_parent_data npu_core_3mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[4].hw },
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[8].hw },
+};
+
+static const struct clk_parent_data npu_e31_3mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[4].hw },
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[8].hw },
+};
+
+static const struct clk_parent_data vi_aclk_root_2mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+};
+
+static const struct clk_parent_data mux_vi_dw_root_2mux1_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data mux_vi_dvp_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data mux_vi_dig_isp_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+};
+
+static const struct clk_parent_data mux_vo_aclk_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+};
+
+static const struct clk_parent_data mux_vo_pixel_root_2mux1_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+	{ .hw = &eic7700_fixed_rate_clks[8].hw },
+};
+
+static const struct clk_parent_data mux_vcdec_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+};
+
+static const struct clk_parent_data mux_vcaclk_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[1].hw },
+	{ .hw = &eic7700_fixed_rate_clks[7].hw },
+};
+
+static const struct clk_parent_data npu_llclk_3mux1_gfree_mux_p[] = {
+	{ .hw = &eic7700_early_clks[1].hw },
+	{ .hw = &eic7700_early_clks[2].hw },
+	{ .hw = &eic7700_fixed_rate_clks[10].hw },
+};
+
+static const struct clk_parent_data mux_bootspi_clk_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_early_clks[4].hw },
+	{ .index = 0 },
+};
+
+static const struct clk_parent_data mux_scpu_core_clk_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_early_clks[5].hw },
+	{ .index = 0 },
+};
+
+static const struct clk_parent_data mux_lpcpu_core_clk_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_early_clks[6].hw },
+	{ .index = 0 },
+};
+
+static const struct clk_parent_data mux_vo_mclk_2mux_ext_mclk_p[] = {
+	{ .hw = &eic7700_early_clks[7].hw },
+	{ .hw = &eic7700_fixed_rate_clks[15].hw },
+};
+
+static const struct clk_parent_data mux_aondma_axi2mux1_gfree_p[] = {
+	{ .hw = &eic7700_early_clks[8].hw },
+	{ .index = 0 },
+};
+
+static const struct clk_parent_data mux_rmii_ref_2mux1_p[] = {
+	{ .hw = &eic7700_early_clks[0].hw },
+	{ .hw = &eic7700_fixed_rate_clks[16].hw },
+};
+
+static const struct clk_parent_data mux_eth_core_2mux1_p[] = {
+	{ .hw = &eic7700_fixed_rate_clks[6].hw },
+	{ .hw = &eic7700_fixed_rate_clks[16].hw },
+};
+
+static const struct clk_parent_data mux_sata_phy_2mux1_p[] = {
+	{ .hw = &eic7700_early_clks[9].hw },
+	{ .hw = &eic7700_fixed_rate_clks[16].hw },
+};
+
+static const struct clk_parent_data mux_syscfg_clk_root_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_early_clks[10].hw },
+	{ .index = 0 },
+};
+
+static const struct clk_parent_data mux_cpu_root_3mux1_gfree_p[] = {
+	{ .hw = &eic7700_pll_clks[1].hw },
+	{ .hw = &eic7700_early_clks[11].hw },
+	{ .index = 0 },
+};
+
+static struct eswin_mux_clock eic7700_mux_clks[] = {
+	ESWIN_MUX(EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+		  "mux_cpu_root_3mux1_gfree", mux_cpu_root_3mux1_gfree_p,
+		  ARRAY_SIZE(mux_cpu_root_3mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 0, 2,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_RMII_REF_2MUX, "mux_rmii_ref_2mux1",
+		  mux_rmii_ref_2mux1_p, ARRAY_SIZE(mux_rmii_ref_2mux1_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_ETH0, 2, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_DSP_ACLK_ROOT_2MUX1_GFREE,
+		  "mux_dsp_aclk_root_2mux1_gfree",
+		  dsp_aclk_root_2mux1_gfree_mux_p,
+		  ARRAY_SIZE(dsp_aclk_root_2mux1_gfree_mux_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_DSP_ACLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_D2D_ACLK_ROOT_2MUX1_GFREE,
+		  "mux_d2d_aclk_root_2mux1_gfree",
+		  d2d_aclk_root_2mux1_gfree_mux_p,
+		  ARRAY_SIZE(d2d_aclk_root_2mux1_gfree_mux_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_D2D_ACLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_DDR_ACLK_ROOT_2MUX1_GFREE,
+		  "mux_ddr_aclk_root_2mux1_gfree",
+		  ddr_aclk_root_2mux1_gfree_mux_p,
+		  ARRAY_SIZE(ddr_aclk_root_2mux1_gfree_mux_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_DDR, 16, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_0,
+		  "mux_mshcore_root_3mux1_0", mshcore_root_3mux1_0_mux_p,
+		  ARRAY_SIZE(mshcore_root_3mux1_0_mux_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_MSHC0_CORE, 0, 1, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_1,
+		  "mux_mshcore_root_3mux1_1", mshcore_root_3mux1_1_mux_p,
+		  ARRAY_SIZE(mshcore_root_3mux1_1_mux_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_MSHC1_CORE, 0, 1, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_2,
+		  "mux_mshcore_root_3mux1_2", mshcore_root_3mux1_2_mux_p,
+		  ARRAY_SIZE(mshcore_root_3mux1_2_mux_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_MSHC2_CORE, 0, 1, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_NPU_LLCLK_3MUX1_GFREE,
+		  "mux_npu_llclk_3mux1_gfree", npu_llclk_3mux1_gfree_mux_p,
+		  ARRAY_SIZE(npu_llclk_3mux1_gfree_mux_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_NPU_LLC, 0, 2,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_NPU_CORE_3MUX1_GFREE,
+		  "mux_npu_core_3mux1_gfree", npu_core_3mux1_gfree_mux_p,
+		  ARRAY_SIZE(npu_core_3mux1_gfree_mux_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_NPU_CORE, 0, 2, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_NPU_E31_3MUX1_GFREE,
+		  "mux_npu_e31_3mux1_gfree", npu_e31_3mux1_gfree_mux_p,
+		  ARRAY_SIZE(npu_e31_3mux1_gfree_mux_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_NPU_CORE, 8, 2, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VI_ACLK_ROOT_2MUX1_GFREE,
+		  "mux_vi_aclk_root_2mux1_gfree",
+		  vi_aclk_root_2mux1_gfree_mux_p,
+		  ARRAY_SIZE(vi_aclk_root_2mux1_gfree_mux_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_ACLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VI_DW_ROOT_2MUX1, "mux_vi_dw_root_2mux1",
+		  mux_vi_dw_root_2mux1_p, ARRAY_SIZE(mux_vi_dw_root_2mux1_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_DWCLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VI_DVP_ROOT_2MUX1_GFREE,
+		  "mux_vi_dvp_root_2mux1_gfree",
+		  mux_vi_dvp_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_vi_dvp_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_DVP, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VI_DIG_ISP_ROOT_2MUX1_GFREE,
+		  "mux_vi_dig_isp_root_2mux1_gfree",
+		  mux_vi_dig_isp_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_vi_dig_isp_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_DIG_ISP, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VO_ACLK_ROOT_2MUX1_GFREE,
+		  "mux_vo_aclk_root_2mux1_gfree",
+		  mux_vo_aclk_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_vo_aclk_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_ACLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VO_PIXEL_ROOT_2MUX1,
+		  "mux_vo_pixel_root_2mux1", mux_vo_pixel_root_2mux1_p,
+		  ARRAY_SIZE(mux_vo_pixel_root_2mux1_p), CLK_SET_RATE_PARENT,
+		  EIC7700_REG_OFFSET_VO_PIXEL, 0, 1, CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VCDEC_ROOT_2MUX1_GFREE,
+		  "mux_vcdec_root_2mux1_gfree", mux_vcdec_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_vcdec_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VCDEC_ROOT, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VCACLK_ROOT_2MUX1_GFREE,
+		  "mux_vcaclk_root_2mux1_gfree",
+		  mux_vcaclk_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_vcaclk_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_ACLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+		  "mux_syscfg_clk_root_2mux1_gfree",
+		  mux_syscfg_clk_root_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_syscfg_clk_root_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SYSCFG, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_BOOTSPI_CLK_2MUX1_GFREE,
+		  "mux_bootspi_clk_2mux1_gfree",
+		  mux_bootspi_clk_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_bootspi_clk_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_BOOTSPI, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_SCPU_CORE_CLK_2MUX1_GFREE,
+		  "mux_scpu_core_clk_2mux1_gfree",
+		  mux_scpu_core_clk_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_scpu_core_clk_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SCPU_CORE, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_LPCPU_CORE_CLK_2MUX1_GFREE,
+		  "mux_lpcpu_core_clk_2mux1_gfree",
+		  mux_lpcpu_core_clk_2mux1_gfree_p,
+		  ARRAY_SIZE(mux_lpcpu_core_clk_2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LPCPU_CORE, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_VO_MCLK_2MUX_EXT_MCLK,
+		  "mux_vo_mclk_2mux_ext_mclk", mux_vo_mclk_2mux_ext_mclk_p,
+		  ARRAY_SIZE(mux_vo_mclk_2mux_ext_mclk_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_MCLK, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_AONDMA_AXI2MUX1_GFREE,
+		  "mux_aondma_axi2mux1_gfree", mux_aondma_axi2mux1_gfree_p,
+		  ARRAY_SIZE(mux_aondma_axi2mux1_gfree_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_AON_DMA, 0, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_ETH_CORE_2MUX1, "mux_eth_core_2mux1",
+		  mux_eth_core_2mux1_p, ARRAY_SIZE(mux_eth_core_2mux1_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_ETH0, 1, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+	ESWIN_MUX(EIC7700_CLK_MUX_SATA_PHY_2MUX1, "mux_sata_phy_2mux1",
+		  mux_sata_phy_2mux1_p, ARRAY_SIZE(mux_sata_phy_2mux1_p),
+		  CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SATA_OOB, 9, 1,
+		  CLK_MUX_ROUND_CLOSEST),
+};
+
+static const struct clk_parent_data mux_cpu_aclk_2mux1_gfree_p[] = {
+	{ .hw = &eic7700_mux_clks[1].hw },
+	{ .hw = &eic7700_mux_clks[0].hw },
+};
+
+static struct eswin_clk_info eic7700_clks[] = {
+	ESWIN_MUX_TYPE(EIC7700_CLK_MUX_CPU_ACLK_2MUX1_GFREE,
+		       "mux_cpu_aclk_2mux1_gfree", mux_cpu_aclk_2mux1_gfree_p,
+		       ARRAY_SIZE(mux_cpu_aclk_2mux1_gfree_p),
+		       CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 20, 1,
+		       CLK_MUX_ROUND_CLOSEST, NULL),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_TRACE_COM_CLK,
+			"gate_clk_cpu_trace_com_clk",
+			EIC7700_CLK_MUX_CPU_ACLK_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 23, 0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_CPU_DIV2,
+			  "fixed_factor_cpu_div2",
+			  EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE, 1, 2, 0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_MIPI_TXESC_DIV10,
+			  "fixed_factor_mipi_txesc_div10",
+			  EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE, 1, 10,
+			  0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_SCPU_BUS_DIV2,
+			  "fixed_factor_scpu_bus_div2",
+			  EIC7700_CLK_MUX_SCPU_CORE_CLK_2MUX1_GFREE, 1, 2, 0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_LPCPU_BUS_DIV2,
+			  "fixed_factor_lpcpu_bus_div2",
+			  EIC7700_CLK_MUX_LPCPU_CORE_CLK_2MUX1_GFREE, 1, 2, 0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_PCIE_CR_DIV2,
+			  "fixed_factor_pcie_cr_div2",
+			  EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE, 1, 2, 0),
+	ESWIN_FACTOR_TYPE(EIC7700_CLK_FIXED_FACTOR_PCIE_AUX_DIV4,
+			  "fixed_factor_pcie_aux_div4",
+			  EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE, 1, 4, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_D2D_ACLK_DYNM,
+		       "divider_d2d_aclk_div_dynm",
+		       EIC7700_CLK_MUX_D2D_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_D2D_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DSP_ACLK_DYNM,
+		       "divider_dsp_aclk_div_dynm",
+		       EIC7700_CLK_MUX_DSP_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_DSP_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+		       "divider_ddr_aclk_div_dynm",
+		       EIC7700_CLK_MUX_DDR_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_DDR, 20, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_ETH_TXCLK_DYNM_0,
+		       "divider_eth_txclk_div_dynm_0",
+		       EIC7700_CLK_MUX_ETH_CORE_2MUX1, 0,
+		       EIC7700_REG_OFFSET_ETH0, 4, 7, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_ETH_TXCLK_DYNM_1,
+		       "divider_eth_txclk_div_dynm_1",
+		       EIC7700_CLK_MUX_ETH_CORE_2MUX1, 0,
+		       EIC7700_REG_OFFSET_ETH1, 4, 7, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_MSHC_CORE_DYNM_0,
+		       "divider_mshc_core_div_dynm_0",
+		       EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_0,
+		       0, EIC7700_REG_OFFSET_MSHC0_CORE, 4, 12,
+		       CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_MSHC_CORE_DYNM_1,
+		       "divider_mshc_core_div_dynm_1",
+		       EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_1,
+		       0, EIC7700_REG_OFFSET_MSHC1_CORE, 4, 12,
+		       CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_MSHC_CORE_DYNM_2,
+		       "divider_mshc_core_div_dynm_2",
+		       EIC7700_CLK_MUX_MSHCORE_ROOT_3MUX1_2,
+		       0, EIC7700_REG_OFFSET_MSHC2_CORE, 4, 12,
+		       CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NPU_CORECLK_DYNM,
+		       "divider_npu_coreclk_div_dynm",
+		       EIC7700_CLK_MUX_NPU_CORE_3MUX1_GFREE,
+		       0, EIC7700_REG_OFFSET_NPU_CORE, 4, 4,
+		       CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NPU_E31_DYNM, "divider_npu_e31_div_dynm",
+		       EIC7700_CLK_MUX_NPU_E31_3MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_NPU_CORE, 12, 4,
+		       CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_ACLK_DYNM, "divider_vi_aclk_div_dynm",
+		       EIC7700_CLK_MUX_VI_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VI_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_DW_DYNM, "divider_vi_dw_div_dynm",
+		       EIC7700_CLK_MUX_VI_DW_ROOT_2MUX1, 0,
+		       EIC7700_REG_OFFSET_VI_DWCLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_DVP_DYNM, "divider_vi_dvp_div_dynm",
+		       EIC7700_CLK_MUX_VI_DVP_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VI_DVP, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_DIG_ISP_DYNM,
+		       "divider_vi_dig_isp_div_dynm",
+		       EIC7700_CLK_MUX_VI_DIG_ISP_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VI_DIG_ISP, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VO_ACLK_DYNM, "divider_vo_aclk_div_dynm",
+		       EIC7700_CLK_MUX_VO_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VO_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VO_PIXEL_DYNM,
+		       "divider_vo_pixel_div_dynm",
+		       EIC7700_CLK_MUX_VO_PIXEL_ROOT_2MUX1, 0,
+		       EIC7700_REG_OFFSET_VO_PIXEL, 4, 6, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VC_ACLK_DYNM, "divider_vc_aclk_div_dynm",
+		       EIC7700_CLK_MUX_VCACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VC_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_JD_DYNM, "divider_jd_div_dynm",
+		       EIC7700_CLK_MUX_VCDEC_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_JD, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_JE_DYNM, "divider_je_div_dynm",
+		       EIC7700_CLK_MUX_VCDEC_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_JE, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VE_DYNM, "divider_ve_div_dynm",
+		       EIC7700_CLK_MUX_VCDEC_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VE, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VD_DYNM, "divider_vd_div_dynm",
+		       EIC7700_CLK_MUX_VCDEC_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_VD, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_G2D_DYNM, "divider_g2d_div_dynm",
+		       EIC7700_CLK_MUX_DSP_ACLK_ROOT_2MUX1_GFREE, 0,
+		       EIC7700_REG_OFFSET_G2D, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NOC_NSP_DYNM, "divider_noc_nsp_div_dynm",
+		       EIC7700_CLK_SPLL2_FOUT1, 0, EIC7700_REG_OFFSET_NOC, 0, 3,
+		       0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_GPU_ACLK_DYNM,
+		       "divider_gpu_aclk_div_dynm", EIC7700_CLK_SPLL0_FOUT1, 0,
+		       EIC7700_REG_OFFSET_GPU_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_HSP_ACLK_DYNM,
+		       "divider_hsp_aclk_div_dynm", EIC7700_CLK_SPLL0_FOUT1, 0,
+		       EIC7700_REG_OFFSET_HSP_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_PCIE_ACLK_DYNM,
+		       "divider_pcie_aclk_div_dynm", EIC7700_CLK_SPLL2_FOUT2, 0,
+		       EIC7700_REG_OFFSET_PCIE_ACLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_NPU_ACLK_DYNM,
+		       "divider_npu_aclk_div_dynm", EIC7700_CLK_SPLL0_FOUT1, 0,
+		       EIC7700_REG_OFFSET_NPU_ACLK, 4,  4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_0,
+		       "divider_vi_shutter_div_dynm_0",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER0, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_1,
+		       "divider_vi_shutter_div_dynm_1",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER1, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_2,
+		       "divider_vi_shutter_div_dynm_2",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER2, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_3,
+		       "divider_vi_shutter_div_dynm_3",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER3, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_4,
+		       "divider_vi_shutter_div_dynm_4",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER4, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VI_SHUTTER_DYNM_5,
+		       "divider_vi_shutter_div_dynm_5",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VI_SHUTTER5, 4, 7, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_IESMCLK_DYNM, "divider_iesmclk_div_dynm",
+		       EIC7700_CLK_SPLL0_FOUT3, 0,
+		       EIC7700_REG_OFFSET_VO_IESMCLK, 4, 4, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_VO_CEC_DYNM, "divider_vo_cec_div_dynm",
+		       EIC7700_CLK_VPLL_FOUT2, 0,
+		       EIC7700_REG_OFFSET_VO_PHY_CLK, 16, 16, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_CRYPTO_DYNM, "divider_crypto_div_dynm",
+		       EIC7700_CLK_SPLL0_FOUT1, 0,
+		       EIC7700_REG_OFFSET_SPACC, 4, 4, 0, ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_AON_RTC_DYNM, "divider_aon_rtc_div_dynm",
+		       EIC7700_CLK_FIXED_FACTOR_CLK_1M_DIV24, 0,
+		       EIC7700_REG_OFFSET_RTC, 21, 11, 0,
+		       ESWIN_PRIV_DIV_MIN_2),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DSPT_ACLK, "gate_dspt_aclk",
+			EIC7700_CLK_DIV_DSP_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_DSP_ACLK, 31, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DSP_0_ACLK_DYNM,
+		       "divider_dsp_0_aclk_div_dynm",
+		       EIC7700_CLK_GATE_DSPT_ACLK, 0,
+		       EIC7700_REG_OFFSET_DSP_CFG, 19, 1, 0, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DSP_1_ACLK_DYNM,
+		       "divider_dsp_1_aclk_div_dynm",
+		       EIC7700_CLK_GATE_DSPT_ACLK, 0,
+		       EIC7700_REG_OFFSET_DSP_CFG, 20, 1, 0, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DSP_2_ACLK_DYNM,
+		       "divider_dsp_2_aclk_div_dynm",
+		       EIC7700_CLK_GATE_DSPT_ACLK, 0,
+		       EIC7700_REG_OFFSET_DSP_CFG, 21, 1, 0, 0),
+	ESWIN_DIV_TYPE(EIC7700_CLK_DIV_DSP_3_ACLK_DYNM,
+		       "divider_dsp_3_aclk_div_dynm",
+		       EIC7700_CLK_GATE_DSPT_ACLK, 0,
+		       EIC7700_REG_OFFSET_DSP_CFG, 22, 1, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_EXT_SRC_CORE_CLK_0,
+			"gate_clk_cpu_ext_src_core_clk_0",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_U84, 28, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_EXT_SRC_CORE_CLK_1,
+			"gate_clk_cpu_ext_src_core_clk_1",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_U84, 29, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_EXT_SRC_CORE_CLK_2,
+			"gate_clk_cpu_ext_src_core_clk_2",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_U84, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_EXT_SRC_CORE_CLK_3,
+			"gate_clk_cpu_ext_src_core_clk_3",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_U84, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_TRACE_CLK_0,
+			"gate_clk_cpu_trace_clk_0",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 24, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_TRACE_CLK_1,
+			"gate_clk_cpu_trace_clk_1",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 25, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_TRACE_CLK_2,
+			"gate_clk_cpu_trace_clk_2",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 26, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CPU_TRACE_CLK_3,
+			"gate_clk_cpu_trace_clk_3",
+			EIC7700_CLK_MUX_CPU_ROOT_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_U84, 27, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NOC_NSP_CLK, "gate_noc_nsp_clk",
+			EIC7700_CLK_DIV_NOC_NSP_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NOC, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_BOOTSPI, "gate_clk_bootspi",
+			EIC7700_CLK_MUX_BOOTSPI_CLK_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_BOOTSPI, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_BOOTSPI_CFG, "gate_clk_bootspi_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_BOOTSPI_CFGCLK,
+			31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_SCPU_CORE, "gate_clk_scpu_core",
+			EIC7700_CLK_MUX_SCPU_CORE_CLK_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SCPU_CORE, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_SCPU_BUS, "gate_clk_scpu_bus",
+			EIC7700_CLK_FIXED_FACTOR_SCPU_BUS_DIV2,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SCPU_BUSCLK, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LPCPU_CORE, "gate_clk_lpcpu_core",
+			EIC7700_CLK_MUX_LPCPU_CORE_CLK_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LPCPU_CORE, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LPCPU_BUS, "gate_clk_lpcpu_bus",
+			EIC7700_CLK_FIXED_FACTOR_LPCPU_BUS_DIV2,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LPCPU_BUSCLK,
+			31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_GPU_ACLK, "gate_gpu_aclk",
+			EIC7700_CLK_DIV_GPU_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_GPU_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_GPU_CFG_CLK, "gate_gpu_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_GPU_CFG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DSPT_CFG_CLK, "gate_dspt_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_DSP_CFG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_D2D_ACLK, "gate_d2d_aclk",
+			EIC7700_CLK_DIV_D2D_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_D2D_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_D2D_CFG_CLK, "gate_d2d_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_D2D_CFG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TCU_ACLK, "gate_tcu_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_TCU_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TCU_CFG_CLK, "gate_tcu_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TCU_CFG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT_CFG_CLK, "gate_ddrt_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_DDR, 9, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT0_P0_ACLK, "gate_ddrt0_p0_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR, 4, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT0_P1_ACLK, "gate_ddrt0_p1_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR, 5, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT0_P2_ACLK, "gate_ddrt0_p2_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR, 6, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT0_P3_ACLK, "gate_ddrt0_p3_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR, 7, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT0_P4_ACLK, "gate_ddrt0_p4_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR, 8, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT1_P0_ACLK, "gate_ddrt1_p0_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR1, 4, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT1_P1_ACLK, "gate_ddrt1_p1_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR1, 5, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT1_P2_ACLK, "gate_ddrt1_p2_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR1, 6, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT1_P3_ACLK, "gate_ddrt1_p3_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR1, 7, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDRT1_P4_ACLK, "gate_ddrt1_p4_aclk",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_DDR1, 8, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_ACLK, "gate_clk_hsp_aclk",
+			EIC7700_CLK_DIV_HSP_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_HSP_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_CFG_CLK, "gate_clk_hsp_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_HSP_CFG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_PCIET_ACLK, "gate_pciet_aclk",
+			EIC7700_CLK_DIV_PCIE_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_PCIE_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_PCIET_CFG_CLK, "gate_pciet_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_PCIE_CFG, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_PCIET_CR_CLK, "gate_pciet_cr_clk",
+			EIC7700_CLK_FIXED_FACTOR_PCIE_CR_DIV2,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_PCIE_CFG, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_PCIET_AUX_CLK, "gate_pciet_aux_clk",
+			EIC7700_CLK_FIXED_FACTOR_PCIE_AUX_DIV4,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_PCIE_CFG, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NPU_ACLK, "gate_npu_aclk",
+			EIC7700_CLK_DIV_NPU_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NPU_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NPU_CFG_CLK, "gate_npu_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_NPU_ACLK, 30,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NPU_LLC_ACLK, "gate_npu_llc_aclk",
+			EIC7700_CLK_MUX_NPU_LLCLK_3MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_NPU_LLC, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NPU_CLK, "gate_npu_clk",
+			EIC7700_CLK_DIV_NPU_CORECLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NPU_CORE, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NPU_E31_CLK, "gate_npu_e31_clk",
+			EIC7700_CLK_DIV_NPU_E31_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NPU_CORE, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_ACLK, "gate_vi_aclk",
+			EIC7700_CLK_DIV_VI_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_CFG_CLK, "gate_vi_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_ACLK, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_DIG_DW_CLK, "gate_vi_dig_dw_clk",
+			EIC7700_CLK_DIV_VI_DW_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_DWCLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_DVP_CLK, "gate_vi_dvp_clk",
+			EIC7700_CLK_DIV_VI_DVP_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_DVP, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_DIG_ISP_CLK, "gate_vi_dig_isp_clk",
+			EIC7700_CLK_DIV_VI_DIG_ISP_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_DIG_ISP, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_0, "gate_vi_shutter_0",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_0, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER0, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_1, "gate_vi_shutter_1",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_1, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER1, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_2, "gate_vi_shutter_2",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_2, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER2, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_3, "gate_vi_shutter_3",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_3, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER3, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_4, "gate_vi_shutter_4",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_4, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER4, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_SHUTTER_5, "gate_vi_shutter_5",
+			EIC7700_CLK_DIV_VI_SHUTTER_DYNM_5, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VI_SHUTTER5, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VI_PHY_TXCLKESC,
+			"gate_vi_phy_txclkesc",
+			EIC7700_CLK_FIXED_FACTOR_MIPI_TXESC_DIV10,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VI_PHY, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_ACLK, "gate_vo_aclk",
+			EIC7700_CLK_DIV_VO_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VO_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_CFG_CLK, "gate_vo_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_ACLK, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_HDMI_IESMCLK,
+			"gate_vo_hdmi_iesmclk", EIC7700_CLK_DIV_IESMCLK_DYNM,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_IESMCLK, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_PIXEL_CLK, "gate_vo_pixel_clk",
+			EIC7700_CLK_DIV_VO_PIXEL_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VO_PIXEL, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_I2S_MCLK, "gate_vo_i2s_mclk",
+			EIC7700_CLK_MUX_VO_MCLK_2MUX_EXT_MCLK,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_MCLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VO_CR_CLK, "gate_vo_cr_clk",
+			EIC7700_CLK_FIXED_FACTOR_MIPI_TXESC_DIV10,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VO_PHY_CLK, 1,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_ACLK, "gate_vc_aclk",
+			EIC7700_CLK_DIV_VC_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VC_ACLK, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_CFG_CLK, "gate_vc_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_JE_CLK, "gate_vc_je_clk",
+			EIC7700_CLK_DIV_JE_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_JE, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_JD_CLK, "gate_vc_jd_clk",
+			EIC7700_CLK_DIV_JD_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_JD, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_VE_CLK, "gate_vc_ve_clk",
+			EIC7700_CLK_DIV_VE_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VE, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_VD_CLK, "gate_vc_vd_clk",
+			EIC7700_CLK_DIV_VD_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_VD, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_G2D_CFG_CLK, "gate_g2d_cfg_clk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_G2D, 28, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_G2D_CLK, "gate_g2d_clk",
+			EIC7700_CLK_DIV_G2D_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_G2D, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_G2D_ACLK, "gate_g2d_aclk",
+			EIC7700_CLK_DIV_G2D_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_G2D, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_AONDMA_CFG, "gate_clk_aondma_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_AON_DMA, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_AONDMA_ACLK, "gate_aondma_aclk",
+			EIC7700_CLK_MUX_AONDMA_AXI2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_AON_DMA, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_AON_ACLK, "gate_aon_aclk",
+			EIC7700_CLK_MUX_AONDMA_AXI2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_AON_DMA, 29, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TIMER_PCLK_0, "gate_timer_pclk_0",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 4, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TIMER_PCLK_1, "gate_timer_pclk_1",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 5, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TIMER_PCLK_2, "gate_timer_pclk_2",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 6, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TIMER_PCLK_3, "gate_timer_pclk_3",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TIMER, 7, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TIMER3_CLK8, "gate_timer3_clk8",
+			EIC7700_CLK_VPLL_FOUT3, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_TIMER, 8, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_RTC_CFG, "gate_clk_rtc_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_RTC, 2, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_RTC, "gate_clk_rtc",
+			EIC7700_CLK_DIV_AON_RTC_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_RTC, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_RMII_REF_0, "gate_hsp_rmii_ref_0",
+			EIC7700_CLK_MUX_RMII_REF_2MUX, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_ETH0, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_RMII_REF_1, "gate_hsp_rmii_ref_1",
+			EIC7700_CLK_MUX_RMII_REF_2MUX, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_ETH1, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_PKA_CFG, "gate_clk_pka_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_PKA, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_SPACC_CFG, "gate_clk_spacc_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SPACC, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_CRYPTO, "gate_clk_crypto",
+			EIC7700_CLK_DIV_CRYPTO_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_SPACC, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_TRNG_CFG, "gate_clk_trng_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_TRNG, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_OTP_CFG, "gate_clk_otp_cfg",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_OTP, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_0, "gate_clk_mailbox_0",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_1, "gate_clk_mailbox_1",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_2, "gate_clk_mailbox_2",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 2, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_3, "gate_clk_mailbox_3",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 3, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_4, "gate_clk_mailbox_4",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 4, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_5, "gate_clk_mailbox_5",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 5, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_6, "gate_clk_mailbox_6",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 6, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_7, "gate_clk_mailbox_7",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 7, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_8, "gate_clk_mailbox_8",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 8, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_9, "gate_clk_mailbox_9",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 9, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_10, "gate_clk_mailbox_10",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 10, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_11, "gate_clk_mailbox_11",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 11, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_12, "gate_clk_mailbox_12",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 12, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_13, "gate_clk_mailbox_13",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 13, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_14, "gate_clk_mailbox_14",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 14, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_MAILBOX_15, "gate_clk_mailbox_15",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN1, 15, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C0_PCLK, "gate_i2c0_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 7, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C1_PCLK, "gate_i2c1_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 8, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C2_PCLK, "gate_i2c2_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 9, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C3_PCLK, "gate_i2c3_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 10, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C4_PCLK, "gate_i2c4_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 11, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C5_PCLK, "gate_i2c5_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 12, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C6_PCLK, "gate_i2c6_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 13, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C7_PCLK, "gate_i2c7_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 14, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C8_PCLK, "gate_i2c8_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 15, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_I2C9_PCLK, "gate_i2c9_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 16, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_WDT0_PCLK, "gate_lsp_wdt0_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 28, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_WDT1_PCLK, "gate_lsp_wdt1_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 29, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_WDT2_PCLK, "gate_lsp_wdt2_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 30, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_WDT3_PCLK, "gate_lsp_wdt3_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_SSI0_PCLK, "gate_lsp_ssi0_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 26, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_SSI1_PCLK, "gate_lsp_ssi1_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 27, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_UART0_PCLK, "gate_lsp_uart0_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_LSP_EN0, 17, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_UART1_PCLK, "gate_lsp_uart1_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 18, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_UART2_PCLK, "gate_lsp_uart2_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_LSP_EN0, 19, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_UART3_PCLK, "gate_lsp_uart3_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 20, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_UART4_PCLK, "gate_lsp_uart4_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 21, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_TIMER_PCLK, "gate_lsp_timer_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+			EIC7700_REG_OFFSET_LSP_EN0, 25, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_FAN_PCLK, "gate_lsp_fan_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_PVT_PCLK, "gate_lsp_pvt_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_LSP_EN0, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_PVT0_CLK, "gate_pvt0_clk",
+			EIC7700_CLK_FIXED_FACTOR_PVT_DIV20, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_LSP_EN1, 16, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_LSP_PVT1_CLK, "gate_pvt1_clk",
+			EIC7700_CLK_FIXED_FACTOR_PVT_DIV20, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_LSP_EN1, 17, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_JE_PCLK, "gate_vc_je_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 2, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_JD_PCLK, "gate_vc_jd_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_VE_PCLK, "gate_vc_ve_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 5, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_VD_PCLK, "gate_vc_vd_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 4, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_VC_MON_PCLK, "gate_vc_mon_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_VC_CLKEN, 3, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_MSHC0_CORE_CLK,
+			"gate_hsp_mshc0_core_clk",
+			EIC7700_CLK_DIV_MSHC_CORE_DYNM_0, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_MSHC0_CORE, 16, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_MSHC1_CORE_CLK,
+			"gate_hsp_mshc1_core_clk",
+			EIC7700_CLK_DIV_MSHC_CORE_DYNM_1, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_MSHC1_CORE, 16, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_MSHC2_CORE_CLK,
+			"gate_hsp_mshc2_core_clk",
+			EIC7700_CLK_DIV_MSHC_CORE_DYNM_2, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_MSHC2_CORE, 16, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_SATA_RBC_CLK,
+			"gate_hsp_sata_rbc_clk", EIC7700_CLK_SPLL1_FOUT2,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SATA_RBC,
+			0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_SATA_OOB_CLK,
+			"gate_hsp_sata_oob_clk", EIC7700_CLK_MUX_SATA_PHY_2MUX1,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_SATA_OOB, 31,
+			0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_DMA0_CLK_TEST,
+			"gate_hsp_dma0_clk_test", EIC7700_CLK_GATE_HSP_ACLK,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_HSP_ACLK, 1, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_DMA0_CLK, "gate_hsp_dma0_clk",
+			EIC7700_CLK_GATE_HSP_ACLK, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_HSP_ACLK, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_ETH0_CORE_CLK,
+			"gate_hsp_eth0_core_clk",
+			EIC7700_CLK_DIV_ETH_TXCLK_DYNM_0, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_ETH0, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_HSP_ETH1_CORE_CLK,
+			"gate_hsp_eth1_core_clk",
+			EIC7700_CLK_DIV_ETH_TXCLK_DYNM_1, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_ETH1, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_AON_I2C0_PCLK, "gate_aon_i2c0_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_I2C0, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_AON_I2C1_PCLK, "gate_aon_i2c1_pclk",
+			EIC7700_CLK_MUX_SYSCFG_CLK_ROOT_2MUX1_GFREE,
+			CLK_SET_RATE_PARENT, EIC7700_REG_OFFSET_I2C1, 31, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDR0_TRACE, "gate_ddr0_trace",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_DDR, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_DDR1_TRACE, "gate_ddr1_trace",
+			EIC7700_CLK_DIV_DDR_ACLK_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_DDR1, 0, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_RNOC_NSP, "gate_rnoc_nsp",
+			EIC7700_CLK_DIV_NOC_NSP_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NOC, 29, 0),
+	ESWIN_GATE_TYPE(EIC7700_CLK_GATE_NOC_WDREF, "gate_noc_wdref",
+			EIC7700_CLK_DIV_NOC_WDREF_DYNM, CLK_SET_RATE_PARENT,
+			EIC7700_REG_OFFSET_NOC, 30, 0),
+};
+
+/*
+ * This clock notifier is called when the rate of clk_pll_cpu clock is to be
+ * changed. The mux_cpu_root_3mux1_gfree clock should save the current parent
+ * clock and switch its parent clock to fixed_factor_u84_core_lp_div2 before
+ * clk_pll_cpu rate will be changed. Then switch its parent clock back after
+ * the clk_pll_cpu rate is completed.
+ */
+static int eic7700_clk_pll_cpu_notifier_cb(struct notifier_block *nb,
+					   unsigned long action, void *data)
+{
+	struct eswin_clock_data *pdata;
+	struct clk_hw *mux_clk;
+	struct clk_hw *lp_clk;
+	int ret = 0;
+
+	pdata = container_of(nb, struct eswin_clock_data, pll_nb);
+
+	mux_clk = &eic7700_mux_clks[0].hw;
+	lp_clk = &eic7700_early_clks[11].hw;
+
+	if (action == PRE_RATE_CHANGE) {
+		pdata->original_clk = clk_hw_get_parent(mux_clk);
+		ret = clk_hw_set_parent(mux_clk, lp_clk);
+	} else if (action == POST_RATE_CHANGE) {
+		ret = clk_hw_set_parent(mux_clk, pdata->original_clk);
+	}
+
+	return notifier_from_errno(ret);
+}
+
+static int eic7700_clk_probe(struct platform_device *pdev)
+{
+	struct eswin_clock_data *clk_data;
+	struct device *dev = &pdev->dev;
+	struct clk *pll_clk;
+	int ret;
+
+	clk_data = eswin_clk_init(pdev, EIC7700_NR_CLKS);
+	if (IS_ERR(clk_data))
+		return dev_err_probe(dev, PTR_ERR(clk_data),
+				     "failed to get clk data!\n");
+
+	ret = eswin_clk_register_fixed_rate(dev, eic7700_fixed_rate_clks,
+					    ARRAY_SIZE(eic7700_fixed_rate_clks),
+					    clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register fixed rate clock\n");
+
+	ret = eswin_clk_register_pll(dev, eic7700_pll_clks,
+				     ARRAY_SIZE(eic7700_pll_clks),
+				     clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register pll clock\n");
+
+	pll_clk = devm_clk_hw_get_clk(dev, &eic7700_pll_clks[1].hw,
+				      "clk_pll_cpu");
+	if (IS_ERR(pll_clk))
+		return dev_err_probe(dev, PTR_ERR(pll_clk),
+				     "failed to get clk_pll_cpu\n");
+
+	clk_data->pll_nb.notifier_call = eic7700_clk_pll_cpu_notifier_cb;
+	ret = devm_clk_notifier_register(dev, pll_clk, &clk_data->pll_nb);
+	if (ret)
+		return ret;
+
+	ret = eswin_clk_register_fixed_factor(dev, eic7700_factor_clks,
+					      ARRAY_SIZE(eic7700_factor_clks),
+					      clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register fixed factor clock\n");
+
+	ret = eswin_clk_register_divider(dev, eic7700_div_clks,
+					 ARRAY_SIZE(eic7700_div_clks),
+					 clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register divider clock\n");
+
+	ret = eswin_clk_register_gate(dev, eic7700_gate_clks,
+				      ARRAY_SIZE(eic7700_gate_clks), clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register gate clock\n");
+
+	ret = eswin_clk_register_clks(dev, eic7700_early_clks,
+				      ARRAY_SIZE(eic7700_early_clks), clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register clock\n");
+
+	ret = eswin_clk_register_mux(dev, eic7700_mux_clks,
+				     ARRAY_SIZE(eic7700_mux_clks), clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "failed to register mux clock\n");
+
+	ret = eswin_clk_register_clks(dev, eic7700_clks,
+				      ARRAY_SIZE(eic7700_clks), clk_data);
+	if (ret)
+		return dev_err_probe(dev, ret, "failed to register clock\n");
+
+	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+					   &clk_data->clk_data);
+}
+
+static const struct of_device_id eic7700_clock_dt_ids[] = {
+	{ .compatible = "eswin,eic7700-clock", },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, eic7700_clock_dt_ids);
+
+static struct platform_driver eic7700_clock_driver = {
+	.probe	= eic7700_clk_probe,
+	.driver = {
+		.name	= "eic7700-clock",
+		.of_match_table	= eic7700_clock_dt_ids,
+	},
+};
+module_platform_driver(eic7700_clock_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yifeng Huang <huangyifeng@eswincomputing.com>");
+MODULE_AUTHOR("Xuyang Dong <dongxuyang@eswincomputing.com>");
+MODULE_DESCRIPTION("ESWIN EIC7700 clock controller driver");
diff --git a/drivers/clk/eswin/clk.c b/drivers/clk/eswin/clk.c
new file mode 100644
index 0000000..e09a52c
--- /dev/null
+++ b/drivers/clk/eswin/clk.c
@@ -0,0 +1,586 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
+ * All rights reserved.
+ *
+ * Authors:
+ *	Yifeng Huang <huangyifeng@eswincomputing.com>
+ *	Xuyang Dong <dongxuyang@eswincomputing.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk-provider.h>
+#include <linux/iopoll.h>
+#include <linux/math.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "common.h"
+
+#define PLL_EN_MASK		GENMASK(1, 0)
+#define PLL_REFDIV_MASK		GENMASK(17, 12)
+#define PLL_FBDIV_MASK		GENMASK(31, 20)
+#define PLL_FRAC_MASK		GENMASK(27, 4)
+#define PLL_POSTDIV1_MASK	GENMASK(10, 8)
+#define PLL_POSTDIV2_MASK	GENMASK(18, 16)
+
+struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
+					size_t nr_clks)
+{
+	struct eswin_clock_data *eclk_data;
+
+	eclk_data = devm_kzalloc(&pdev->dev,
+				 struct_size(eclk_data, clk_data.hws, nr_clks),
+				 GFP_KERNEL);
+	if (!eclk_data)
+		return ERR_PTR(-ENOMEM);
+
+	eclk_data->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(eclk_data->base))
+		return ERR_PTR(-EINVAL);
+
+	eclk_data->clk_data.num = nr_clks;
+	spin_lock_init(&eclk_data->lock);
+
+	return eclk_data;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_init);
+
+/**
+ * eswin_calc_pll - calculate PLL values
+ * @frac_val: fractional divider
+ * @fbdiv_val: feedback divider
+ * @rate: reference rate
+ * @parent_rate: parent rate
+ *
+ *   Calculate PLL values for frac and fbdiv:
+ *	fbdiv = rate * 4 / parent_rate
+ *	frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate
+ */
+static void eswin_calc_pll(u32 *frac_val, u32 *fbdiv_val, unsigned long rate,
+			   unsigned long parent_rate)
+{
+	u32 rem;
+	u64 tmp;
+
+	/* step 1: rate * 4 */
+	tmp = rate * 4;
+	/* step 2: use do_div() to get the quotient(tmp) and remainder(rem) */
+	rem = do_div(tmp, (u32)parent_rate);
+	/* fbdiv = rate * 4 / parent_rate */
+	*fbdiv_val = (u32)tmp;
+	/*
+	 * step 3: rem << 24
+	 * 24: 24-bit fractional accuracy
+	 */
+	tmp = (u64)rem << 24;
+	/* step 4: use do_div() to get the quotient(tmp) */
+	do_div(tmp, (u32)parent_rate);
+	/* frac = (rate * 4 % parent_rate * (2 ^ 24)) / parent_rate */
+	*frac_val = (u32)tmp;
+}
+
+static inline struct eswin_clk_pll *to_pll_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct eswin_clk_pll, hw);
+}
+
+static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct eswin_clk_pll *clk = to_pll_clk(hw);
+	u32 frac_val, fbdiv_val, val, mask;
+	int ret;
+
+	eswin_calc_pll(&frac_val, &fbdiv_val, rate, parent_rate);
+
+	/* First, disable pll */
+	val = readl_relaxed(clk->ctrl_reg0);
+	val &= ~PLL_EN_MASK;
+	val |= FIELD_PREP(PLL_EN_MASK, 0);
+	writel_relaxed(val, clk->ctrl_reg0);
+
+	val = readl_relaxed(clk->ctrl_reg0);
+	val &= ~(PLL_REFDIV_MASK | PLL_FBDIV_MASK);
+	val |= FIELD_PREP(PLL_FBDIV_MASK, fbdiv_val);
+	val |= FIELD_PREP(PLL_REFDIV_MASK, 1);
+	writel_relaxed(val, clk->ctrl_reg0);
+
+	val = readl_relaxed(clk->ctrl_reg1);
+	val &= ~PLL_FRAC_MASK;
+	val |= FIELD_PREP(PLL_FRAC_MASK, frac_val);
+	writel_relaxed(val, clk->ctrl_reg1);
+
+	val = readl_relaxed(clk->ctrl_reg2);
+	val &= ~(PLL_POSTDIV1_MASK | PLL_POSTDIV2_MASK);
+	val |= FIELD_PREP(PLL_POSTDIV1_MASK, 1);
+	val |= FIELD_PREP(PLL_POSTDIV2_MASK, 1);
+	writel_relaxed(val, clk->ctrl_reg2);
+
+	/* Last, enable pll */
+	val = readl_relaxed(clk->ctrl_reg0);
+	val &= ~PLL_EN_MASK;
+	val |= FIELD_PREP(PLL_EN_MASK, 1);
+	writel_relaxed(val, clk->ctrl_reg0);
+
+	/* Usually the pll will lock in 50us */
+	mask = GENMASK(clk->lock_shift + clk->lock_width - 1, clk->lock_shift);
+	ret = readl_poll_timeout(clk->status_reg, val, val & mask, 1, 50 * 2);
+	if (ret)
+		pr_err("failed to lock the pll!\n");
+
+	return ret;
+}
+
+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct eswin_clk_pll *clk = to_pll_clk(hw);
+	u64 fbdiv_val, frac_val, tmp;
+	u32 rem, val;
+
+	val = readl_relaxed(clk->ctrl_reg0);
+	val &= PLL_FBDIV_MASK;
+	fbdiv_val = (val >> clk->fbdiv_shift);
+
+	val = readl_relaxed(clk->ctrl_reg1);
+	val &= PLL_FRAC_MASK;
+	frac_val = (val >> clk->frac_shift);
+
+	/* rate = 24000000 * (fbdiv + frac / (2 ^ 24)) / 4 */
+	tmp = parent_rate * frac_val;
+	rem = do_div(tmp, BIT(24));
+	if (rem)
+		tmp = parent_rate * fbdiv_val + tmp + 1;
+	else
+		tmp = parent_rate * fbdiv_val + tmp;
+
+	do_div(tmp, 4);
+
+	return tmp;
+}
+
+static int clk_pll_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct eswin_clk_pll *clk = to_pll_clk(hw);
+
+	req->rate = clamp(req->rate, clk->min_rate, clk->max_rate);
+	req->min_rate = clk->min_rate;
+	req->max_rate = clk->max_rate;
+
+	return 0;
+}
+
+int eswin_clk_register_fixed_rate(struct device *dev,
+				  struct eswin_fixed_rate_clock *clks,
+				  int nums, struct eswin_clock_data *data)
+{
+	struct clk_hw *clk_hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk_hw = devm_clk_hw_register_fixed_rate(dev, clks[i].name,
+							 NULL, clks[i].flags,
+							 clks[i].rate);
+		if (IS_ERR(clk_hw))
+			return PTR_ERR(clk_hw);
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_rate);
+
+static const struct clk_ops eswin_clk_pll_ops = {
+	.set_rate = clk_pll_set_rate,
+	.recalc_rate = clk_pll_recalc_rate,
+	.determine_rate = clk_pll_determine_rate,
+};
+
+int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
+			   int nums, struct eswin_clock_data *data)
+{
+	struct eswin_clk_pll *p_clk = NULL;
+	struct clk_init_data init;
+	struct clk_hw *clk_hw;
+	int i, ret;
+
+	p_clk = devm_kzalloc(dev, sizeof(*p_clk) * nums, GFP_KERNEL);
+	if (!p_clk)
+		return -ENOMEM;
+
+	for (i = 0; i < nums; i++) {
+		p_clk->id = clks[i].id;
+		p_clk->ctrl_reg0 = data->base + clks[i].ctrl_reg0;
+		p_clk->fbdiv_shift = clks[i].fbdiv_shift;
+
+		p_clk->ctrl_reg1 = data->base + clks[i].ctrl_reg1;
+		p_clk->frac_shift = clks[i].frac_shift;
+
+		p_clk->ctrl_reg2 = data->base + clks[i].ctrl_reg2;
+
+		p_clk->status_reg = data->base + clks[i].status_reg;
+		p_clk->lock_shift = clks[i].lock_shift;
+		p_clk->lock_width = clks[i].lock_width;
+
+		p_clk->max_rate = clks[i].max_rate;
+		p_clk->min_rate = clks[i].min_rate;
+
+		init.name = clks[i].name;
+		init.flags = 0;
+		init.parent_data = clks[i].parent_data;
+		init.num_parents = 1;
+		init.ops = &eswin_clk_pll_ops;
+		p_clk->hw.init = &init;
+
+		clk_hw = &p_clk->hw;
+
+		ret = devm_clk_hw_register(dev, clk_hw);
+		if (ret)
+			return ret;
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+		p_clk++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_pll);
+
+int eswin_clk_register_fixed_factor(struct device *dev,
+				    struct eswin_fixed_factor_clock *clks,
+				    int nums, struct eswin_clock_data *data)
+{
+	struct clk_hw *clk_hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk_hw = devm_clk_hw_register_fixed_factor_index(dev, clks[i].name,
+								 clks[i].parent_data->index,
+								 clks[i].flags, clks[i].mult,
+								 clks[i].div);
+
+		if (IS_ERR(clk_hw))
+			return PTR_ERR(clk_hw);
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_fixed_factor);
+
+int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
+			   int nums, struct eswin_clock_data *data)
+{
+	struct clk_hw *clk_hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk_hw = devm_clk_hw_register_mux_parent_data_table(dev, clks[i].name,
+								    clks[i].parent_data,
+								    clks[i].num_parents,
+								    clks[i].flags,
+								    data->base + clks[i].reg,
+								    clks[i].shift, clks[i].width,
+								    clks[i].mux_flags,
+								    clks[i].table, &data->lock);
+
+		if (IS_ERR(clk_hw))
+			return PTR_ERR(clk_hw);
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_mux);
+
+static unsigned int _eswin_get_val(unsigned int div, unsigned long flags,
+				   u8 width)
+{
+	unsigned int maxdiv;
+
+	maxdiv = clk_div_mask(width);
+	div = div > maxdiv ? maxdiv : div;
+
+	if (flags & ESWIN_PRIV_DIV_MIN_2)
+		return (div < 2) ? 2 : div;
+
+	return div;
+}
+
+static unsigned int eswin_div_get_val(unsigned long rate,
+				      unsigned long parent_rate, u8 width,
+				      unsigned long flags)
+{
+	unsigned int div;
+
+	div = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+
+	return _eswin_get_val(div, flags, width);
+}
+
+static inline struct eswin_divider_clock *to_div_clk(struct clk_hw *hw)
+{
+	return container_of(hw, struct eswin_divider_clock, hw);
+}
+
+static int clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct eswin_divider_clock *dclk = to_div_clk(hw);
+	unsigned long flags;
+	unsigned int value;
+	u32 val;
+
+	value = eswin_div_get_val(rate, parent_rate, dclk->width,
+				  dclk->priv_flag);
+
+	spin_lock_irqsave(dclk->lock, flags);
+
+	val = readl_relaxed(dclk->ctrl_reg);
+	val &= ~(clk_div_mask(dclk->width) << dclk->shift);
+	val |= (u32)value << dclk->shift;
+	writel_relaxed(val, dclk->ctrl_reg);
+
+	spin_unlock_irqrestore(dclk->lock, flags);
+
+	return 0;
+}
+
+static unsigned long clk_div_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct eswin_divider_clock *dclk = to_div_clk(hw);
+	unsigned int div, val;
+
+	val = readl_relaxed(dclk->ctrl_reg) >> dclk->shift;
+	val &= clk_div_mask(dclk->width);
+	div = _eswin_get_val(val, dclk->priv_flag, dclk->width);
+
+	return DIV_ROUND_UP_ULL((u64)parent_rate, div);
+}
+
+static int eswin_clk_bestdiv(unsigned long rate,
+			     unsigned long best_parent_rate, u8 width,
+			     unsigned long flags)
+{
+	unsigned long bestdiv, up_rate, down_rate;
+	int up, down;
+
+	if (!rate)
+		rate = 1;
+
+	/* closest round */
+	up = DIV_ROUND_UP_ULL((u64)best_parent_rate, rate);
+	down = best_parent_rate / rate;
+
+	up_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, up);
+	down_rate = DIV_ROUND_UP_ULL((u64)best_parent_rate, down);
+
+	bestdiv = (rate - up_rate) <= (down_rate - rate) ? up : down;
+
+	return bestdiv;
+}
+
+static int clk_div_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct eswin_divider_clock *dclk = to_div_clk(hw);
+	int div;
+
+	div = eswin_clk_bestdiv(req->rate, req->best_parent_rate, dclk->width,
+				dclk->priv_flag);
+	div = _eswin_get_val(div, dclk->priv_flag, dclk->width);
+	req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, div);
+
+	return 0;
+}
+
+static const struct clk_ops eswin_clk_div_ops = {
+	.set_rate = clk_div_set_rate,
+	.recalc_rate = clk_div_recalc_rate,
+	.determine_rate = clk_div_determine_rate,
+};
+
+struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
+				     const char *name,
+				     const struct clk_hw *parent_hw,
+				     unsigned long flags, void __iomem *reg,
+				     u8 shift, u8 width,
+				     unsigned long clk_divider_flags,
+				     unsigned long priv_flag, spinlock_t *lock)
+{
+	struct eswin_divider_clock *dclk;
+	struct clk_init_data init;
+	struct clk_hw *clk_hw;
+	int ret;
+
+	dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
+	if (!dclk)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &eswin_clk_div_ops;
+	init.flags = flags;
+	init.parent_hws = &parent_hw;
+	init.num_parents = 1;
+
+	/* struct clk_divider assignments */
+	dclk->id = id;
+	dclk->ctrl_reg = reg;
+	dclk->shift = shift;
+	dclk->width = width;
+	dclk->div_flags = clk_divider_flags;
+	dclk->priv_flag = priv_flag;
+	dclk->lock = lock;
+	dclk->hw.init = &init;
+
+	/* register the clock */
+	clk_hw = &dclk->hw;
+	ret = devm_clk_hw_register(dev, clk_hw);
+	if (ret) {
+		dev_err(dev, "failed to register divider clock!\n");
+		return ERR_PTR(ret);
+	}
+
+	return clk_hw;
+}
+EXPORT_SYMBOL_GPL(eswin_register_clkdiv);
+
+int eswin_clk_register_divider(struct device *dev,
+			       struct eswin_divider_clock *clks,
+			       int nums, struct eswin_clock_data *data)
+{
+	struct clk_hw *clk_hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk_hw = devm_clk_hw_register_divider_parent_data(dev, clks[i].name,
+								  clks[i].parent_data,
+								  clks[i].flags,
+								  data->base + clks[i].reg,
+								  clks[i].shift, clks[i].width,
+								  clks[i].div_flags, &data->lock);
+
+		if (IS_ERR(clk_hw))
+			return PTR_ERR(clk_hw);
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_divider);
+
+int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
+			    int nums, struct eswin_clock_data *data)
+{
+	struct clk_hw *clk_hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		clk_hw = devm_clk_hw_register_gate_parent_data(dev, clks[i].name,
+							       clks[i].parent_data,
+							       clks[i].flags,
+							       data->base + clks[i].reg,
+							       clks[i].bit_idx, clks[i].gate_flags,
+							       &data->lock);
+
+		if (IS_ERR(clk_hw))
+			return PTR_ERR(clk_hw);
+
+		clks[i].hw = *clk_hw;
+		data->clk_data.hws[clks[i].id] = clk_hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_gate);
+
+int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
+			    int nums, struct eswin_clock_data *data)
+{
+	struct eswin_clk_info *info;
+	const struct clk_hw *phw = NULL;
+	struct clk_hw *hw;
+	int i;
+
+	for (i = 0; i < nums; i++) {
+		info = &clks[i];
+		switch (info->type) {
+		case CLK_FIXED_FACTOR: {
+			const struct eswin_fixed_factor_clock *factor;
+
+			factor = &info->data.factor;
+			phw = data->clk_data.hws[info->pid];
+			hw = devm_clk_hw_register_fixed_factor_parent_hw(dev, factor->name, phw,
+									 factor->flags,
+									 factor->mult,
+									 factor->div);
+			break;
+		}
+		case CLK_MUX: {
+			const struct eswin_mux_clock *mux = &info->data.mux;
+
+			hw = devm_clk_hw_register_mux_parent_data_table(dev, mux->name,
+									mux->parent_data,
+									mux->num_parents,
+									mux->flags,
+									data->base + mux->reg,
+									mux->shift, mux->width,
+									mux->mux_flags,
+									mux->table, &data->lock);
+			break;
+		}
+		case CLK_DIVIDER: {
+			const struct eswin_divider_clock *div = &info->data.div;
+
+			phw = data->clk_data.hws[info->pid];
+			if (div->priv_flag)
+				hw = eswin_register_clkdiv(dev, div->id, div->name, phw,
+							   div->flags, data->base + div->reg,
+							   div->shift, div->width, div->div_flags,
+							   div->priv_flag, &data->lock);
+			else
+				hw = devm_clk_hw_register_divider_parent_hw(dev, div->name, phw,
+									    div->flags,
+									    data->base + div->reg,
+									    div->shift, div->width,
+									    div->div_flags,
+									    &data->lock);
+			break;
+		}
+		case CLK_GATE: {
+			const struct eswin_gate_clock *gate = &info->data.gate;
+
+			phw = data->clk_data.hws[info->pid];
+			hw = devm_clk_hw_register_gate_parent_hw(dev, gate->name, phw,
+								 gate->flags,
+								 data->base + gate->reg,
+								 gate->bit_idx, gate->gate_flags,
+								 &data->lock);
+			break;
+		}
+		default:
+			dev_err(dev, "Unidentifiable clock type!\n");
+			return -EINVAL;
+		}
+		if (IS_ERR(hw))
+			return PTR_ERR(hw);
+
+		info->hw = *hw;
+		data->clk_data.hws[info->id] = hw;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(eswin_clk_register_clks);
diff --git a/drivers/clk/eswin/common.h b/drivers/clk/eswin/common.h
new file mode 100644
index 0000000..d8e5e65
--- /dev/null
+++ b/drivers/clk/eswin/common.h
@@ -0,0 +1,340 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2026, Beijing ESWIN Computing Technology Co., Ltd..
+ * All rights reserved.
+ *
+ * Authors:
+ *	Yifeng Huang <huangyifeng@eswincomputing.com>
+ *	Xuyang Dong <dongxuyang@eswincomputing.com>
+ */
+
+#ifndef __ESWIN_COMMON_H__
+#define __ESWIN_COMMON_H__
+
+#define APLL_HIGH_FREQ	983040000
+#define APLL_LOW_FREQ	225792000
+#define PLL_HIGH_FREQ	1800000000
+#define PLL_LOW_FREQ	24000000
+
+/*
+ * ESWIN_PRIV_DIV_MIN_2: If ESWIN_PRIV_DIV_MIN_2 is set, the minimum value of
+ *	the register is 2, i.e. the minimum division ratio is 2.
+ */
+#define ESWIN_PRIV_DIV_MIN_2	BIT(0)
+
+enum eswin_clk_type {
+	CLK_FIXED_FACTOR,
+	CLK_MUX,
+	CLK_DIVIDER,
+	CLK_GATE,
+};
+
+struct eswin_clock_data {
+	void __iomem *base;
+	struct clk_hw *original_clk;
+	struct notifier_block pll_nb;
+	spinlock_t lock; /* protect register read-modify-write cycle */
+	struct clk_hw_onecell_data clk_data;
+};
+
+struct eswin_divider_clock {
+	struct clk_hw hw;
+	unsigned int id;
+	const char *name;
+	const struct clk_parent_data *parent_data;
+	void __iomem *ctrl_reg; /* register address of the divider clock */
+	unsigned long flags;
+	unsigned long reg; /* register offset */
+	u8 shift;
+	u8 width;
+	unsigned long div_flags;
+	unsigned long priv_flag;
+	spinlock_t *lock; /* protect register read-modify-write cycle */
+};
+
+struct eswin_fixed_rate_clock {
+	struct clk_hw hw;
+	unsigned int id;
+	const char *name;
+	unsigned long flags;
+	unsigned long rate;
+};
+
+struct eswin_fixed_factor_clock {
+	struct clk_hw hw;
+	unsigned int id;
+	const char *name;
+	const struct clk_parent_data *parent_data;
+	unsigned long mult;
+	unsigned long div;
+	unsigned long flags;
+};
+
+struct eswin_gate_clock {
+	struct clk_hw hw;
+	unsigned int id;
+	const char *name;
+	const struct clk_parent_data *parent_data;
+	unsigned long flags;
+	unsigned long reg;
+	u8 bit_idx;
+	u8 gate_flags;
+};
+
+struct eswin_mux_clock {
+	struct clk_hw hw;
+	unsigned int id;
+	const char *name;
+	const struct clk_parent_data *parent_data;
+	u8 num_parents;
+	unsigned long flags;
+	unsigned long reg;
+	u8 shift;
+	u8 width;
+	u8 mux_flags;
+	u32 *table;
+};
+
+struct eswin_pll_clock {
+	struct clk_hw hw;
+	u32 id;
+	const char *name;
+	const struct clk_parent_data *parent_data;
+	const u32 ctrl_reg0;
+	const u8 fbdiv_shift;
+
+	const u32 ctrl_reg1;
+	const u8 frac_shift;
+
+	const u32 ctrl_reg2;
+
+	const u32 status_reg;
+	const u8 lock_shift;
+	const u8 lock_width;
+
+	const u64 max_rate;
+	const u64 min_rate;
+};
+
+struct eswin_clk_pll {
+	struct clk_hw hw;
+	u32 id;
+	void __iomem *ctrl_reg0;
+	u8 fbdiv_shift;
+
+	void __iomem *ctrl_reg1;
+	u8 frac_shift;
+
+	void __iomem *ctrl_reg2;
+
+	void __iomem *status_reg;
+	u8 lock_shift;
+	u8 lock_width;
+
+	u64 max_rate;
+	u64 min_rate;
+};
+
+struct eswin_clk_info {
+	unsigned int type;
+	unsigned int pid;
+	unsigned int id;
+	struct clk_hw hw;
+	union {
+		struct eswin_divider_clock div;
+		struct eswin_fixed_factor_clock factor;
+		struct eswin_gate_clock gate;
+		struct eswin_mux_clock mux;
+	} data;
+};
+
+struct eswin_clock_data *eswin_clk_init(struct platform_device *pdev,
+					size_t nr_clks);
+int eswin_clk_register_fixed_rate(struct device *dev,
+				  struct eswin_fixed_rate_clock *clks,
+				  int nums, struct eswin_clock_data *data);
+int eswin_clk_register_pll(struct device *dev, struct eswin_pll_clock *clks,
+			   int nums, struct eswin_clock_data *data);
+int eswin_clk_register_fixed_factor(struct device *dev,
+				    struct eswin_fixed_factor_clock *clks,
+				    int nums, struct eswin_clock_data *data);
+int eswin_clk_register_mux(struct device *dev, struct eswin_mux_clock *clks,
+			   int nums, struct eswin_clock_data *data);
+int eswin_clk_register_divider(struct device *dev,
+			       struct eswin_divider_clock *clks,
+			       int nums, struct eswin_clock_data *data);
+int eswin_clk_register_gate(struct device *dev, struct eswin_gate_clock *clks,
+			    int nums, struct eswin_clock_data *data);
+int eswin_clk_register_clks(struct device *dev, struct eswin_clk_info *clks,
+			    int nums, struct eswin_clock_data *data);
+struct clk_hw *eswin_register_clkdiv(struct device *dev, unsigned int id,
+				     const char *name,
+				     const struct clk_hw *parent_hw,
+				     unsigned long flags, void __iomem *reg,
+				     u8 shift, u8 width,
+				     unsigned long clk_divider_flags,
+				     unsigned long priv_flag, spinlock_t *lock);
+
+#define ESWIN_DIV(_id, _name, _pdata, _flags, _reg, _shift, _width,	\
+		  _dflags, _pflag)					\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.flags		= _flags,				\
+		.reg		= _reg,					\
+		.shift		= _shift,				\
+		.width		= _width,				\
+		.div_flags	= _dflags,				\
+		.priv_flag	= _pflag,				\
+	}
+
+#define ESWIN_DIV_TYPE(_id, _name, _pid, _flags, _reg, _shift, _width,	\
+		       _dflags, _pflag)					\
+	{								\
+		.type	= CLK_DIVIDER,					\
+		.pid	= _pid,						\
+		.id	= _id,						\
+		.data	= {						\
+				.div = {				\
+					.name	= _name,		\
+					.flags		= _flags,	\
+					.reg		= _reg,		\
+					.shift		= _shift,	\
+					.width		= _width,	\
+					.div_flags	= _dflags,	\
+					.priv_flag	= _pflag,	\
+				},					\
+		},							\
+	}
+
+#define ESWIN_FACTOR(_id, _name, _pdata, _mult, _div, _flags)		\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.mult		= _mult,				\
+		.div		= _div,					\
+		.flags		= _flags,				\
+	}
+
+#define ESWIN_FACTOR_TYPE(_id, _name, _pid, _mult, _div, _flags)	\
+	{								\
+		.type	= CLK_FIXED_FACTOR,				\
+		.pid	= _pid,						\
+		.id	= _id,						\
+		.data	= {						\
+				.factor = {				\
+					    .name	= _name,	\
+					    .mult	= _mult,	\
+					    .div	= _div,		\
+					    .flags	= _flags,	\
+				},					\
+		},							\
+	}
+
+#define ESWIN_FIXED(_id, _name, _flags, _rate)				\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.flags		= _flags,				\
+		.rate		= _rate,				\
+	}
+
+#define ESWIN_GATE(_id, _name, _pdata, _flags, _reg, _idx, _gflags)	\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.flags		= _flags,				\
+		.reg		= _reg,					\
+		.bit_idx	= _idx,					\
+		.gate_flags	= _gflags,				\
+	}
+
+#define ESWIN_GATE_TYPE(_id, _name, _pid, _flags, _reg, _idx, _gflags)	\
+	{								\
+		.type	= CLK_GATE,					\
+		.pid	= _pid,						\
+		.id	= _id,						\
+		.data	= {						\
+				.gate = {				\
+					.name	= _name,		\
+					.flags		= _flags,	\
+					.reg		= _reg,		\
+					.bit_idx	= _idx,		\
+					.gate_flags	= _gflags,	\
+				},					\
+		},							\
+	}
+
+#define ESWIN_MUX(_id, _name, _pdata, _num_parents, _flags, _reg,	\
+		  _shift, _width, _mflags)				\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.num_parents	= _num_parents,				\
+		.flags		= _flags,				\
+		.reg		= _reg,					\
+		.shift		= _shift,				\
+		.width		= _width,				\
+		.mux_flags	= _mflags,				\
+		.table		= NULL,					\
+	}
+
+#define ESWIN_MUX_TBL(_id, _name, _pdata, _num_parents, _flags, _reg,	\
+		      _shift, _width, _mflags, _table)			\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.num_parents	= _num_parents,				\
+		.flags		= _flags,				\
+		.reg		= _reg,					\
+		.shift		= _shift,				\
+		.width		= _width,				\
+		.mux_flags	= _mflags,				\
+		.table		= _table,				\
+	}
+
+#define ESWIN_MUX_TYPE(_id, _name, _pdata, _num_parents, _flags, _reg,	\
+		       _shift, _width, _mflags, _table)			\
+	{								\
+		.type	= CLK_MUX,					\
+		.id	= _id,						\
+		.data	= {						\
+				.mux = {				\
+					.name	= _name,		\
+					.parent_data	= _pdata,	\
+					.num_parents	= _num_parents,	\
+					.flags		= _flags,	\
+					.reg		= _reg,		\
+					.shift		= _shift,	\
+					.width		= _width,	\
+					.mux_flags	= _mflags,	\
+					.table		= _table,	\
+				},					\
+		},							\
+	}
+
+#define ESWIN_PLL(_id, _name, _pdata, _reg0, _fb_shift, _reg1,		\
+		  _frac_shift, _reg2, _reg, _lock_shift, _lock_width,	\
+		  _max_rate, _min_rate)					\
+	{								\
+		.id		= _id,					\
+		.name		= _name,				\
+		.parent_data	= _pdata,				\
+		.ctrl_reg0	= _reg0,				\
+		.fbdiv_shift	= _fb_shift,				\
+		.ctrl_reg1	= _reg1,				\
+		.frac_shift	= _frac_shift,				\
+		.ctrl_reg2	= _reg2,				\
+		.status_reg	= _reg,					\
+		.lock_shift	= _lock_shift,				\
+		.lock_width	= _lock_width,				\
+		.max_rate	= _max_rate,				\
+		.min_rate	= _min_rate,				\
+	}
+
+#endif /* __ESWIN_COMMON_H__ */
diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c
index 89ed774..4048c16 100644
--- a/drivers/clk/imx/clk-fracn-gppll.c
+++ b/drivers/clk/imx/clk-fracn-gppll.c
@@ -85,9 +85,11 @@ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = {
 	PLL_FRACN_GP(519750000U, 173, 25, 100, 1, 8),
 	PLL_FRACN_GP(498000000U, 166, 0, 1, 0, 8),
 	PLL_FRACN_GP(484000000U, 121, 0, 1, 0, 6),
+	PLL_FRACN_GP(477400000U, 119, 35, 100, 0, 6),
 	PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9),
 	PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12),
 	PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10),
+	PLL_FRACN_GP(333333333U, 125, 0, 1, 1, 9),
 	PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10),
 	PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12),
 	PLL_FRACN_GP(241900000U, 201, 584, 1000, 0, 20),
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index f726c00..35e6b59 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -188,9 +188,11 @@ static void of_assigned_ldb_sels(struct device_node *node,
 		}
 		if (clkspec.np != node || clkspec.args[0] >= IMX6QDL_CLK_END) {
 			pr_err("ccm: parent clock %d not in ccm\n", index);
+			of_node_put(clkspec.np);
 			return;
 		}
 		parent = clkspec.args[0];
+		of_node_put(clkspec.np);
 
 		rc = of_parse_phandle_with_args(node, "assigned-clocks",
 				"#clock-cells", index, &clkspec);
@@ -198,9 +200,11 @@ static void of_assigned_ldb_sels(struct device_node *node,
 			return;
 		if (clkspec.np != node || clkspec.args[0] >= IMX6QDL_CLK_END) {
 			pr_err("ccm: child clock %d not in ccm\n", index);
+			of_node_put(clkspec.np);
 			return;
 		}
 		child = clkspec.args[0];
+		of_node_put(clkspec.np);
 
 		if (child != IMX6QDL_CLK_LDB_DI0_SEL &&
 		    child != IMX6QDL_CLK_LDB_DI1_SEL)
@@ -238,8 +242,11 @@ static bool pll6_bypassed(struct device_node *node)
 			return false;
 
 		if (clkspec.np == node &&
-		    clkspec.args[0] == IMX6QDL_PLL6_BYPASS)
+		    clkspec.args[0] == IMX6QDL_PLL6_BYPASS) {
+			of_node_put(clkspec.np);
 			break;
+		}
+		of_node_put(clkspec.np);
 	}
 
 	/* PLL6 bypass is not part of the assigned clock list */
@@ -249,6 +256,9 @@ static bool pll6_bypassed(struct device_node *node)
 	ret = of_parse_phandle_with_args(node, "assigned-clock-parents",
 					 "#clock-cells", index, &clkspec);
 
+	if (!ret)
+		of_node_put(clkspec.np);
+
 	if (clkspec.args[0] != IMX6QDL_CLK_PLL6)
 		return true;
 
diff --git a/drivers/clk/imx/clk-imx8-acm.c b/drivers/clk/imx/clk-imx8-acm.c
index 790f7e4..07dca6f 100644
--- a/drivers/clk/imx/clk-imx8-acm.c
+++ b/drivers/clk/imx/clk-imx8-acm.c
@@ -371,7 +371,8 @@ static int imx8_acm_clk_probe(struct platform_device *pdev)
 	for (i = 0; i < priv->soc_data->num_sels; i++) {
 		hws[sels[i].clkid] = devm_clk_hw_register_mux_parent_data_table(dev,
 										sels[i].name, sels[i].parents,
-										sels[i].num_parents, 0,
+										sels[i].num_parents,
+										CLK_SET_RATE_NO_REPARENT,
 										base + sels[i].reg,
 										sels[i].shift, sels[i].width,
 										0, NULL, NULL);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index f70ed23..cedc8a0 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -237,7 +237,7 @@ static const char * const imx8mq_dsi_esc_sels[] = {"osc_25m", "sys2_pll_100m", "
 static const char * const imx8mq_csi1_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
 					      "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
-static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
+static const char * const imx8mq_csi1_phy_sels[] = {"osc_25m", "sys2_pll_333m", "sys2_pll_100m", "sys1_pll_800m",
 					     "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
@@ -246,7 +246,7 @@ static const char * const imx8mq_csi1_esc_sels[] = {"osc_25m", "sys2_pll_100m",
 static const char * const imx8mq_csi2_core_sels[] = {"osc_25m", "sys1_pll_266m", "sys2_pll_250m", "sys1_pll_800m",
 					      "sys2_pll_1000m", "sys3_pll_out", "audio_pll2_out", "video_pll1_out", };
 
-static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_125m", "sys2_pll_100m", "sys1_pll_800m",
+static const char * const imx8mq_csi2_phy_sels[] = {"osc_25m", "sys2_pll_333m", "sys2_pll_100m", "sys1_pll_800m",
 					     "sys2_pll_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", };
 
 static const char * const imx8mq_csi2_esc_sels[] = {"osc_25m", "sys2_pll_100m", "sys1_pll_80m", "sys1_pll_800m",
diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
index 7552aaa..39600ee 100644
--- a/drivers/clk/imx/clk-pll14xx.c
+++ b/drivers/clk/imx/clk-pll14xx.c
@@ -151,7 +151,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
 	/* First try if we can get the desired rate from one of the static entries */
 	tt = imx_get_pll_settings(pll, rate);
 	if (tt) {
-		pr_debug("%s: in=%ld, want=%ld, Using PLL setting from table\n",
+		pr_debug("%s: in=%lu, want=%lu, Using PLL setting from table\n",
 			 clk_hw_get_name(&pll->hw), prate, rate);
 		t->rate = tt->rate;
 		t->mdiv = tt->mdiv;
@@ -173,7 +173,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
 
 	if (rate >= rate_min && rate <= rate_max) {
 		kdiv = pll1443x_calc_kdiv(mdiv, pdiv, sdiv, rate, prate);
-		pr_debug("%s: in=%ld, want=%ld Only adjust kdiv %ld -> %d\n",
+		pr_debug("%s: in=%lu, want=%lu Only adjust kdiv %ld -> %d\n",
 			 clk_hw_get_name(&pll->hw), prate, rate,
 			 FIELD_GET(KDIV_MASK, pll_div_ctl1), kdiv);
 		fout = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
@@ -211,7 +211,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
 		}
 	}
 found:
-	pr_debug("%s: in=%ld, want=%ld got=%d (pdiv=%d sdiv=%d mdiv=%d kdiv=%d)\n",
+	pr_debug("%s: in=%lu, want=%lu got=%u (pdiv=%d sdiv=%d mdiv=%d kdiv=%d)\n",
 		 clk_hw_get_name(&pll->hw), prate, rate, t->rate, t->pdiv, t->sdiv,
 		 t->mdiv, t->kdiv);
 }
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 41eb385..1fbd801 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -11,6 +11,13 @@
 
 #include "clk.h"
 
+/*
+ * The VF610_CLK_END corresponds to ones defined in
+ * include/dt-bindings/clock/vf610-clock.h
+ * It shall be the value of the last defined clock +1
+ */
+#define VF610_CLK_END 196
+
 #define CCM_CCR			(ccm_base + 0x00)
 #define CCM_CSR			(ccm_base + 0x04)
 #define CCM_CCSR		(ccm_base + 0x08)
@@ -313,6 +320,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
 	clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0));
 	clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1));
+	clk[VF610_CLK_ESW] = imx_clk_gate2("esw", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(8));
+	clk[VF610_CLK_ESW_MAC_TAB0] = imx_clk_gate2("esw_tab0", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(12));
+	clk[VF610_CLK_ESW_MAC_TAB1] = imx_clk_gate2("esw_tab1", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(13));
+	clk[VF610_CLK_ESW_MAC_TAB2] = imx_clk_gate2("esw_tab2", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(14));
+	clk[VF610_CLK_ESW_MAC_TAB3] = imx_clk_gate2("esw_tab3", "ipg_bus", CCM_CCGR10, CCM_CCGRx_CGn(15));
 
 	clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
 
diff --git a/drivers/clk/microchip/clk-mpfs-ccc.c b/drivers/clk/microchip/clk-mpfs-ccc.c
index 3a3ea2d..0a76a1a 100644
--- a/drivers/clk/microchip/clk-mpfs-ccc.c
+++ b/drivers/clk/microchip/clk-mpfs-ccc.c
@@ -178,7 +178,7 @@ static int mpfs_ccc_register_outputs(struct device *dev, struct mpfs_ccc_out_hw_
 			return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
 					     out_hw->id);
 
-		data->hw_data.hws[out_hw->id] = &out_hw->divider.hw;
+		data->hw_data.hws[out_hw->id - 2] = &out_hw->divider.hw;
 	}
 
 	return 0;
@@ -234,6 +234,10 @@ static int mpfs_ccc_probe(struct platform_device *pdev)
 	unsigned int num_clks;
 	int ret;
 
+	/*
+	 * If DLLs get added here, mpfs_ccc_register_outputs() currently packs
+	 * sparse clock IDs in the hws array
+	 */
 	num_clks = ARRAY_SIZE(mpfs_ccc_pll_clks) + ARRAY_SIZE(mpfs_ccc_pll0out_clks) +
 		   ARRAY_SIZE(mpfs_ccc_pll1out_clks);
 
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index bd0bc8e7..3123771 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -126,9 +126,11 @@ static const struct clk_div_table clk_table2[] = {
 static const struct clk_ops clk_double_div_ops;
 static const struct clk_ops clk_pm_cpu_ops;
 
+#define __reg(__x) ((void __iomem __force *)(__x))
+
 #define PERIPH_GATE(_name, _bit)		\
 struct clk_gate gate_##_name = {		\
-	.reg = (void *)CLK_DIS,			\
+	.reg = __reg(CLK_DIS),			\
 	.bit_idx = _bit,			\
 	.hw.init = &(struct clk_init_data){	\
 		.ops =  &clk_gate_ops,		\
@@ -137,7 +139,7 @@ struct clk_gate gate_##_name = {		\
 
 #define PERIPH_MUX(_name, _shift)		\
 struct clk_mux mux_##_name = {			\
-	.reg = (void *)TBG_SEL,			\
+	.reg = __reg(TBG_SEL),			\
 	.shift = _shift,			\
 	.mask = 3,				\
 	.hw.init = &(struct clk_init_data){	\
@@ -147,8 +149,8 @@ struct clk_mux mux_##_name = {			\
 
 #define PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2)	\
 struct clk_double_div rate_##_name = {		\
-	.reg1 = (void *)_reg1,			\
-	.reg2 = (void *)_reg2,			\
+	.reg1 = __reg(_reg1),			\
+	.reg2 = __reg(_reg2),			\
 	.shift1 = _shift1,			\
 	.shift2 = _shift2,			\
 	.hw.init = &(struct clk_init_data){	\
@@ -158,7 +160,7 @@ struct clk_double_div rate_##_name = {		\
 
 #define PERIPH_DIV(_name, _reg, _shift, _table)	\
 struct clk_divider rate_##_name = {		\
-	.reg = (void *)_reg,			\
+	.reg = __reg(_reg),			\
 	.table = _table,			\
 	.shift = _shift,			\
 	.hw.init = &(struct clk_init_data){	\
@@ -168,10 +170,10 @@ struct clk_divider rate_##_name = {		\
 
 #define PERIPH_PM_CPU(_name, _shift1, _reg, _shift2)	\
 struct clk_pm_cpu muxrate_##_name = {		\
-	.reg_mux = (void *)TBG_SEL,		\
+	.reg_mux = __reg(TBG_SEL),		\
 	.mask_mux = 3,				\
 	.shift_mux = _shift1,			\
-	.reg_div = (void *)_reg,		\
+	.reg_div = __reg(_reg),			\
 	.shift_div = _shift2,			\
 	.hw.init = &(struct clk_init_data){	\
 		.ops =  &clk_pm_cpu_ops,	\
diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
index a277c43..df21ef5f 100644
--- a/drivers/clk/qcom/Kconfig
+++ b/drivers/clk/qcom/Kconfig
@@ -19,33 +19,77 @@
 
 if COMMON_CLK_QCOM
 
+config CLK_ELIZA_DISPCC
+	tristate "Eliza Display Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_ELIZA_GCC
+	help
+	  Support for the display clock controllers on Eliza SoCs.
+	  Say Y if you want to support display devices and functionality such as
+	  splash screen.
+
+config CLK_ELIZA_GCC
+	tristate "Eliza Global Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
+	help
+	  Support for the global clock controller on Eliza devices.
+	  Say Y if you want to use peripheral devices such as UART, SPI,
+	  I2C, USB, UFS, SDCC, etc.
+
+config CLK_ELIZA_TCSRCC
+	tristate "Eliza TCSR Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
+	help
+	  Support for the TCSR clock controller on Eliza devices.
+	  Say Y if you want to use peripheral devices such as USB/PCIe/UFS.
+
 config CLK_GLYMUR_DISPCC
-	tristate "GLYMUR Display Clock Controller"
+	tristate "Glymur Display Clock Controller"
 	depends on ARM64 || COMPILE_TEST
 	select CLK_GLYMUR_GCC
 	help
 	  Support for the display clock controllers on Qualcomm
-	  Technologies, Inc. GLYMUR devices.
+	  Technologies, Inc. Glymur devices.
 	  Say Y if you want to support display devices and functionality such as
 	  splash screen.
 
 config CLK_GLYMUR_GCC
-	tristate "GLYMUR Global Clock Controller"
+	tristate "Glymur Global Clock Controller"
 	depends on ARM64 || COMPILE_TEST
 	select QCOM_GDSC
 	help
-	  Support for the global clock controller on GLYMUR devices.
+	  Support for the global clock controller on Glymur devices.
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  I2C, USB, UFS, SDCC, etc.
 
+config CLK_GLYMUR_GPUCC
+	tristate "GLYMUR Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_GLYMUR_GCC
+	help
+	  Support for the graphics clock controller on GLYMUR devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
 config CLK_GLYMUR_TCSRCC
-	tristate "GLYMUR TCSR Clock Controller"
+	tristate "Glymur TCSR Clock Controller"
 	depends on ARM64 || COMPILE_TEST
 	select QCOM_GDSC
 	help
-	  Support for the TCSR clock controller on GLYMUR devices.
+	  Support for the TCSR clock controller on Glymur devices.
 	  Say Y if you want to use peripheral devices such as USB/PCIe/EDP.
 
+config CLK_GLYMUR_VIDEOCC
+	tristate "Glymur Video Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select CLK_GLYMUR_GCC
+	help
+	  Support for the video clock controller on Glymur devices.
+	  Say Y if you want to support video devices and functionality such as
+	  video encode and decode.
+
 config CLK_KAANAPALI_CAMCC
 	tristate "Kaanapali Camera Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -101,6 +145,16 @@
 	  Say Y if you want to support video devices and functionality such as
 	  video encode/decode.
 
+config CLK_NORD_GCC
+	tristate "Nord Global Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select QCOM_GDSC
+	help
+	  Support for the global clock controller on Nord devices.
+	  Say Y if you want to use peripheral devices such as UART,
+	  SPI, I2C, USB, SD/UFS, PCIe etc. The clock controller is a combination
+	  of GCC, SE_GCC, NE_GCC and NW_GCC.
+
 config CLK_X1E80100_CAMCC
 	tristate "X1E80100 Camera Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -314,6 +368,14 @@
 	  Say Y if you want to use peripheral devices such as UART, SPI,
 	  i2c, USB, SD/eMMC, etc.
 
+config IPQ_GCC_5210
+	tristate "IPQ5210 Global Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	help
+	  Support for the global clock controller on ipq5210 devices.
+	  Say Y if you want to use peripheral devices such as UART, SPI,
+	  i2c, USB, SD/eMMC, etc.
+
 config IPQ_GCC_5332
 	tristate "IPQ5332 Global Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -622,6 +684,13 @@
 	  Say Y if you want to use multimedia devices or peripheral
 	  devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
 
+config CLK_NORD_TCSRCC
+	tristate "Nord TCSR Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	help
+	  Support for the TCSR clock controller on Nord devices.
+	  Say Y if you want to use peripheral devices such as PCIe, USB, UFS etc.
+
 config SA_CAMCC_8775P
 	tristate "SA8775P Camera Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -1481,6 +1550,15 @@
 	  Say Y if you want to support graphics controller devices and
 	  functionality such as 3D graphics.
 
+config SM_GPUCC_8750
+	tristate "SM8750 Graphics Clock Controller"
+	depends on ARM64 || COMPILE_TEST
+	select SM_GCC_8750
+	help
+	  Support for the graphics clock controller on SM8750 devices.
+	  Say Y if you want to support graphics controller devices and
+	  functionality such as 3D graphics.
+
 config SM_LPASSCC_6115
 	tristate "SM6115 Low Power Audio Subsystem (LPASS) Clock Controller"
 	depends on ARM64 || COMPILE_TEST
@@ -1579,10 +1657,10 @@
 config SM_VIDEOCC_8350
 	tristate "SM8350 Video Clock Controller"
 	depends on ARM64 || COMPILE_TEST
-	select SM_GCC_8350
+	depends on SM_GCC_8350 || SC_GCC_8280XP
 	select QCOM_GDSC
 	help
-	  Support for the video clock controller on SM8350 devices.
+	  Support for the video clock controller on SM8350 or SC8280XP devices.
 	  Say Y if you want to support video devices and functionality such as
 	  video encode and decode.
 
diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index 6b0ad88..89d07c3 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -20,16 +20,23 @@
 # Keep alphabetically sorted by config
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
+obj-$(CONFIG_CLK_ELIZA_DISPCC) += dispcc-eliza.o
+obj-$(CONFIG_CLK_ELIZA_GCC) += gcc-eliza.o
+obj-$(CONFIG_CLK_ELIZA_TCSRCC) += tcsrcc-eliza.o
 obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o
 obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o
 obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o
+obj-$(CONFIG_CLK_GLYMUR_GPUCC) += gpucc-glymur.o gxclkctl-kaanapali.o
 obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o
+obj-$(CONFIG_CLK_GLYMUR_VIDEOCC) += videocc-glymur.o
 obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o
 obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o
+obj-$(CONFIG_CLK_NORD_GCC) += gcc-nord.o negcc-nord.o nwgcc-nord.o segcc-nord.o
+obj-$(CONFIG_CLK_NORD_TCSRCC) += tcsrcc-nord.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
@@ -43,6 +50,7 @@
 obj-$(CONFIG_IPQ_CMN_PLL) += ipq-cmn-pll.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
 obj-$(CONFIG_IPQ_GCC_5018) += gcc-ipq5018.o
+obj-$(CONFIG_IPQ_GCC_5210) += gcc-ipq5210.o
 obj-$(CONFIG_IPQ_GCC_5332) += gcc-ipq5332.o
 obj-$(CONFIG_IPQ_GCC_5424) += gcc-ipq5424.o
 obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
@@ -180,6 +188,7 @@
 obj-$(CONFIG_SM_GPUCC_8450) += gpucc-sm8450.o
 obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o
 obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o
+obj-$(CONFIG_SM_GPUCC_8750) += gpucc-sm8750.o gxclkctl-kaanapali.o
 obj-$(CONFIG_SM_GPUCC_MILOS) += gpucc-milos.o
 obj-$(CONFIG_SM_LPASSCC_6115) += lpasscc-sm6115.o
 obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o
diff --git a/drivers/clk/qcom/apss-ipq5424.c b/drivers/clk/qcom/apss-ipq5424.c
index 2d622c1..1662c83 100644
--- a/drivers/clk/qcom/apss-ipq5424.c
+++ b/drivers/clk/qcom/apss-ipq5424.c
@@ -211,7 +211,7 @@ static struct clk_alpha_pll *ipa5424_apss_plls[] = {
 	&ipq5424_apss_pll,
 };
 
-static struct qcom_cc_driver_data ipa5424_apss_driver_data = {
+static const struct qcom_cc_driver_data ipa5424_apss_driver_data = {
 	.alpha_plls = ipa5424_apss_plls,
 	.num_alpha_plls = ARRAY_SIZE(ipa5424_apss_plls),
 };
diff --git a/drivers/clk/qcom/cambistmclkcc-kaanapali.c b/drivers/clk/qcom/cambistmclkcc-kaanapali.c
index 066c108..6028d8f 100644
--- a/drivers/clk/qcom/cambistmclkcc-kaanapali.c
+++ b/drivers/clk/qcom/cambistmclkcc-kaanapali.c
@@ -6,9 +6,7 @@
 #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/pm_runtime.h>
 #include <linux/regmap.h>
 
 #include <dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h>
@@ -385,7 +383,7 @@ static struct clk_alpha_pll *cam_bist_mclk_cc_kaanapali_plls[] = {
 	&cam_bist_mclk_cc_pll0,
 };
 
-static u32 cam_bist_mclk_cc_kaanapali_critical_cbcrs[] = {
+static const u32 cam_bist_mclk_cc_kaanapali_critical_cbcrs[] = {
 	0x40e0, /* CAM_BIST_MCLK_CC_SLEEP_CLK */
 };
 
@@ -397,7 +395,7 @@ static const struct regmap_config cam_bist_mclk_cc_kaanapali_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_bist_mclk_cc_kaanapali_driver_data = {
+static const struct qcom_cc_driver_data cam_bist_mclk_cc_kaanapali_driver_data = {
 	.alpha_plls = cam_bist_mclk_cc_kaanapali_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_plls),
 	.clk_cbcrs = cam_bist_mclk_cc_kaanapali_critical_cbcrs,
diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c
index d889a8f..5df12ac 100644
--- a/drivers/clk/qcom/cambistmclkcc-sm8750.c
+++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c
@@ -402,7 +402,7 @@ static struct clk_alpha_pll *cam_bist_mclk_cc_sm8750_plls[] = {
 	&cam_bist_mclk_cc_pll0,
 };
 
-static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = {
+static const u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = {
 	0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */
 };
 
@@ -414,7 +414,7 @@ static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = {
+static const struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = {
 	.alpha_plls = cam_bist_mclk_cc_sm8750_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls),
 	.clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-kaanapali.c b/drivers/clk/qcom/camcc-kaanapali.c
index 8296799..af54864 100644
--- a/drivers/clk/qcom/camcc-kaanapali.c
+++ b/drivers/clk/qcom/camcc-kaanapali.c
@@ -6,9 +6,7 @@
 #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/pm_runtime.h>
 #include <linux/regmap.h>
 
 #include <dt-bindings/clock/qcom,kaanapali-camcc.h>
@@ -2602,7 +2600,7 @@ static struct clk_alpha_pll *cam_cc_kaanapali_plls[] = {
 	&cam_cc_pll7,
 };
 
-static u32 cam_cc_kaanapali_critical_cbcrs[] = {
+static const u32 cam_cc_kaanapali_critical_cbcrs[] = {
 	0x21398, /* CAM_CC_DRV_AHB_CLK */
 	0x21390, /* CAM_CC_DRV_XO_CLK */
 	0x21364, /* CAM_CC_GDSC_CLK */
@@ -2617,7 +2615,7 @@ static const struct regmap_config cam_cc_kaanapali_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_kaanapali_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_kaanapali_driver_data = {
 	.alpha_plls = cam_cc_kaanapali_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_kaanapali_plls),
 	.clk_cbcrs = cam_cc_kaanapali_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-milos.c b/drivers/clk/qcom/camcc-milos.c
index 0077c9c..409d470 100644
--- a/drivers/clk/qcom/camcc-milos.c
+++ b/drivers/clk/qcom/camcc-milos.c
@@ -2104,7 +2104,7 @@ static struct clk_alpha_pll *cam_cc_milos_plls[] = {
 	&cam_cc_pll6,
 };
 
-static u32 cam_cc_milos_critical_cbcrs[] = {
+static const u32 cam_cc_milos_critical_cbcrs[] = {
 	0x25038, /* CAM_CC_GDSC_CLK */
 	0x2505c, /* CAM_CC_SLEEP_CLK */
 };
@@ -2117,7 +2117,7 @@ static const struct regmap_config cam_cc_milos_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_milos_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_milos_driver_data = {
 	.alpha_plls = cam_cc_milos_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_milos_plls),
 	.clk_cbcrs = cam_cc_milos_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-qcs615.c b/drivers/clk/qcom/camcc-qcs615.c
index c063a3b..8377126 100644
--- a/drivers/clk/qcom/camcc-qcs615.c
+++ b/drivers/clk/qcom/camcc-qcs615.c
@@ -1556,7 +1556,7 @@ static const struct regmap_config cam_cc_qcs615_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_qcs615_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_qcs615_driver_data = {
 	.alpha_plls = cam_cc_qcs615_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_qcs615_plls),
 };
diff --git a/drivers/clk/qcom/camcc-sc8180x.c b/drivers/clk/qcom/camcc-sc8180x.c
index 388fedf..016f37d 100644
--- a/drivers/clk/qcom/camcc-sc8180x.c
+++ b/drivers/clk/qcom/camcc-sc8180x.c
@@ -7,7 +7,6 @@
 #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,sc8180x-camcc.h>
@@ -63,6 +62,7 @@ static const struct alpha_pll_config cam_cc_pll0_config = {
 
 static struct clk_alpha_pll cam_cc_pll0 = {
 	.offset = 0x0,
+	.config = &cam_cc_pll0_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -138,6 +138,7 @@ static const struct alpha_pll_config cam_cc_pll1_config = {
 
 static struct clk_alpha_pll cam_cc_pll1 = {
 	.offset = 0x1000,
+	.config = &cam_cc_pll1_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -167,6 +168,7 @@ static const struct alpha_pll_config cam_cc_pll2_config = {
 
 static struct clk_alpha_pll cam_cc_pll2 = {
 	.offset = 0x2000,
+	.config = &cam_cc_pll2_config,
 	.vco_table = regera_vco,
 	.num_vco = ARRAY_SIZE(regera_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_REGERA],
@@ -219,6 +221,7 @@ static const struct alpha_pll_config cam_cc_pll3_config = {
 
 static struct clk_alpha_pll cam_cc_pll3 = {
 	.offset = 0x3000,
+	.config = &cam_cc_pll3_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -248,6 +251,7 @@ static const struct alpha_pll_config cam_cc_pll4_config = {
 
 static struct clk_alpha_pll cam_cc_pll4 = {
 	.offset = 0x4000,
+	.config = &cam_cc_pll4_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -277,6 +281,7 @@ static const struct alpha_pll_config cam_cc_pll5_config = {
 
 static struct clk_alpha_pll cam_cc_pll5 = {
 	.offset = 0x4078,
+	.config = &cam_cc_pll5_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -306,6 +311,7 @@ static const struct alpha_pll_config cam_cc_pll6_config = {
 
 static struct clk_alpha_pll cam_cc_pll6 = {
 	.offset = 0x40f0,
+	.config = &cam_cc_pll6_config,
 	.vco_table = trion_vco,
 	.num_vco = ARRAY_SIZE(trion_vco),
 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
@@ -2813,6 +2819,21 @@ static const struct qcom_reset_map cam_cc_sc8180x_resets[] = {
 	[CAM_CC_MCLK7_BCR] = { 0x50e0 },
 };
 
+static struct clk_alpha_pll *cam_cc_sc8180x_plls[] = {
+	&cam_cc_pll0,
+	&cam_cc_pll1,
+	&cam_cc_pll2,
+	&cam_cc_pll3,
+	&cam_cc_pll4,
+	&cam_cc_pll5,
+	&cam_cc_pll6,
+};
+
+static const u32 cam_cc_sc8180x_critical_cbcrs[] = {
+	0xc1e4, /* CAM_CC_GDSC_CLK */
+	0xc200, /* CAM_CC_SLEEP_CLK */
+};
+
 static const struct regmap_config cam_cc_sc8180x_regmap_config = {
 	.reg_bits = 32,
 	.reg_stride = 4,
@@ -2821,6 +2842,13 @@ static const struct regmap_config cam_cc_sc8180x_regmap_config = {
 	.fast_io = true,
 };
 
+static const struct qcom_cc_driver_data cam_cc_sc8180x_driver_data = {
+	.alpha_plls = cam_cc_sc8180x_plls,
+	.num_alpha_plls = ARRAY_SIZE(cam_cc_sc8180x_plls),
+	.clk_cbcrs = cam_cc_sc8180x_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(cam_cc_sc8180x_critical_cbcrs),
+};
+
 static const struct qcom_cc_desc cam_cc_sc8180x_desc = {
 	.config = &cam_cc_sc8180x_regmap_config,
 	.clks = cam_cc_sc8180x_clocks,
@@ -2829,6 +2857,8 @@ static const struct qcom_cc_desc cam_cc_sc8180x_desc = {
 	.num_resets = ARRAY_SIZE(cam_cc_sc8180x_resets),
 	.gdscs = cam_cc_sc8180x_gdscs,
 	.num_gdscs = ARRAY_SIZE(cam_cc_sc8180x_gdscs),
+	.use_rpm = true,
+	.driver_data = &cam_cc_sc8180x_driver_data,
 };
 
 static const struct of_device_id cam_cc_sc8180x_match_table[] = {
@@ -2839,40 +2869,7 @@ MODULE_DEVICE_TABLE(of, cam_cc_sc8180x_match_table);
 
 static int cam_cc_sc8180x_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_sc8180x_desc);
-	if (IS_ERR(regmap)) {
-		pm_runtime_put(&pdev->dev);
-		return PTR_ERR(regmap);
-	}
-
-	clk_trion_pll_configure(&cam_cc_pll0, regmap, &cam_cc_pll0_config);
-	clk_trion_pll_configure(&cam_cc_pll1, regmap, &cam_cc_pll1_config);
-	clk_regera_pll_configure(&cam_cc_pll2, regmap, &cam_cc_pll2_config);
-	clk_trion_pll_configure(&cam_cc_pll3, regmap, &cam_cc_pll3_config);
-	clk_trion_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config);
-	clk_trion_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config);
-	clk_trion_pll_configure(&cam_cc_pll6, regmap, &cam_cc_pll6_config);
-
-	/* Keep some clocks always enabled */
-	qcom_branch_set_clk_en(regmap, 0xc1e4); /* CAM_CC_GDSC_CLK */
-	qcom_branch_set_clk_en(regmap, 0xc200); /* CAM_CC_SLEEP_CLK */
-
-	ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sc8180x_desc, regmap);
-
-	pm_runtime_put(&pdev->dev);
-
-	return ret;
+	return qcom_cc_probe(pdev, &cam_cc_sc8180x_desc);
 }
 
 static struct platform_driver cam_cc_sc8180x_driver = {
diff --git a/drivers/clk/qcom/camcc-sm8450.c b/drivers/clk/qcom/camcc-sm8450.c
index ef8cf54..1891262 100644
--- a/drivers/clk/qcom/camcc-sm8450.c
+++ b/drivers/clk/qcom/camcc-sm8450.c
@@ -2915,7 +2915,7 @@ static struct clk_alpha_pll *cam_cc_sm8450_plls[] = {
 	&cam_cc_pll8,
 };
 
-static u32 cam_cc_sm8450_critical_cbcrs[] = {
+static const u32 cam_cc_sm8450_critical_cbcrs[] = {
 	0x1320c, /* CAM_CC_GDSC_CLK */
 };
 
@@ -3030,7 +3030,7 @@ static struct gdsc *cam_cc_sm8450_gdscs[] = {
 	[TITAN_TOP_GDSC] = &titan_top_gdsc,
 };
 
-static struct qcom_cc_driver_data cam_cc_sm8450_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_sm8450_driver_data = {
 	.alpha_plls = cam_cc_sm8450_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_sm8450_plls),
 	.clk_cbcrs = cam_cc_sm8450_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c
index b8ece8a..34d53e2 100644
--- a/drivers/clk/qcom/camcc-sm8550.c
+++ b/drivers/clk/qcom/camcc-sm8550.c
@@ -3517,7 +3517,7 @@ static struct clk_alpha_pll *cam_cc_sm8550_plls[] = {
 	&cam_cc_pll12,
 };
 
-static u32 cam_cc_sm8550_critical_cbcrs[] = {
+static const u32 cam_cc_sm8550_critical_cbcrs[] = {
 	0x1419c, /* CAM_CC_GDSC_CLK */
 	0x142cc, /* CAM_CC_SLEEP_CLK */
 };
@@ -3530,7 +3530,7 @@ static const struct regmap_config cam_cc_sm8550_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_sm8550_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_sm8550_driver_data = {
 	.alpha_plls = cam_cc_sm8550_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_sm8550_plls),
 	.clk_cbcrs = cam_cc_sm8550_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-sm8650.c b/drivers/clk/qcom/camcc-sm8650.c
index 8b38890..9dea43e 100644
--- a/drivers/clk/qcom/camcc-sm8650.c
+++ b/drivers/clk/qcom/camcc-sm8650.c
@@ -3533,7 +3533,7 @@ static struct clk_alpha_pll *cam_cc_sm8650_plls[] = {
 	&cam_cc_pll10,
 };
 
-static u32 cam_cc_sm8650_critical_cbcrs[] = {
+static const u32 cam_cc_sm8650_critical_cbcrs[] = {
 	0x132ec, /* CAM_CC_GDSC_CLK */
 	0x13308, /* CAM_CC_SLEEP_CLK */
 	0x13314, /* CAM_CC_DRV_XO_CLK */
@@ -3548,7 +3548,7 @@ static const struct regmap_config cam_cc_sm8650_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_sm8650_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_sm8650_driver_data = {
 	.alpha_plls = cam_cc_sm8650_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_sm8650_plls),
 	.clk_cbcrs = cam_cc_sm8650_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-sm8750.c b/drivers/clk/qcom/camcc-sm8750.c
index a797b78..6618b07 100644
--- a/drivers/clk/qcom/camcc-sm8750.c
+++ b/drivers/clk/qcom/camcc-sm8750.c
@@ -2651,7 +2651,7 @@ static struct clk_alpha_pll *cam_cc_sm8750_plls[] = {
 	&cam_cc_pll6,
 };
 
-static u32 cam_cc_sm8750_critical_cbcrs[] = {
+static const u32 cam_cc_sm8750_critical_cbcrs[] = {
 	0x113c4, /* CAM_CC_DRV_AHB_CLK */
 	0x113c0, /* CAM_CC_DRV_XO_CLK */
 	0x1137c, /* CAM_CC_GDSC_CLK */
@@ -2666,7 +2666,7 @@ static const struct regmap_config cam_cc_sm8750_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_sm8750_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_sm8750_driver_data = {
 	.alpha_plls = cam_cc_sm8750_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_sm8750_plls),
 	.clk_cbcrs = cam_cc_sm8750_critical_cbcrs,
diff --git a/drivers/clk/qcom/camcc-x1e80100.c b/drivers/clk/qcom/camcc-x1e80100.c
index cbcc1c9..81f579f 100644
--- a/drivers/clk/qcom/camcc-x1e80100.c
+++ b/drivers/clk/qcom/camcc-x1e80100.c
@@ -2434,7 +2434,7 @@ static struct clk_alpha_pll *cam_cc_x1e80100_plls[] = {
 	&cam_cc_pll8,
 };
 
-static u32 cam_cc_x1e80100_critical_cbcrs[] = {
+static const u32 cam_cc_x1e80100_critical_cbcrs[] = {
 	0x13a9c, /* CAM_CC_GDSC_CLK */
 	0x13ab8, /* CAM_CC_SLEEP_CLK */
 };
@@ -2447,7 +2447,7 @@ static const struct regmap_config cam_cc_x1e80100_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data cam_cc_x1e80100_driver_data = {
+static const struct qcom_cc_driver_data cam_cc_x1e80100_driver_data = {
 	.alpha_plls = cam_cc_x1e80100_plls,
 	.num_alpha_plls = ARRAY_SIZE(cam_cc_x1e80100_plls),
 	.clk_cbcrs = cam_cc_x1e80100_critical_cbcrs,
diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index fc696b6..6064a0e 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -1117,6 +1117,8 @@ static const struct frac_entry frac_table_pixel[] = {
 	{ 4, 9 },
 	{ 1, 1 },
 	{ 2, 3 },
+	{ 16, 35},
+	{ 4, 15},
 	{ }
 };
 
diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c
index 547729b..339a6bb 100644
--- a/drivers/clk/qcom/clk-rpmh.c
+++ b/drivers/clk/qcom/clk-rpmh.c
@@ -349,6 +349,10 @@ DEFINE_CLK_RPMH_ARC(bi_tcxo, "xo.lvl", 0x3, 2);
 DEFINE_CLK_RPMH_ARC(bi_tcxo, "xo.lvl", 0x3, 4);
 DEFINE_CLK_RPMH_ARC(qlink, "qphy.lvl", 0x1, 4);
 
+DEFINE_CLK_RPMH_VRM(ln_bb_clk1, _a1, "lnbclka1", 1);
+DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _a1, "lnbclka2", 1);
+DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a1, "lnbclka3", 1);
+
 DEFINE_CLK_RPMH_VRM(ln_bb_clk1, _a2, "lnbclka1", 2);
 DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _a2, "lnbclka2", 2);
 DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a2, "lnbclka3", 2);
@@ -372,6 +376,8 @@ DEFINE_CLK_RPMH_VRM(rf_clk3, _d, "rfclkd3", 1);
 DEFINE_CLK_RPMH_VRM(rf_clk4, _d, "rfclkd4", 1);
 
 DEFINE_CLK_RPMH_VRM(rf_clk3, _a2, "rfclka3", 2);
+DEFINE_CLK_RPMH_VRM(rf_clk4, _a2, "rfclka4", 2);
+DEFINE_CLK_RPMH_VRM(rf_clk5, _a2, "rfclka5", 2);
 
 DEFINE_CLK_RPMH_VRM(clk1, _a1, "clka1", 1);
 DEFINE_CLK_RPMH_VRM(clk2, _a1, "clka2", 1);
@@ -940,6 +946,44 @@ static const struct clk_rpmh_desc clk_rpmh_kaanapali = {
 	.num_clks = ARRAY_SIZE(kaanapali_rpmh_clocks),
 };
 
+static struct clk_hw *eliza_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_CLK1]	= &clk_rpmh_clk6_a2.hw,
+	[RPMH_LN_BB_CLK1_A]	= &clk_rpmh_clk6_a2_ao.hw,
+	[RPMH_LN_BB_CLK3]	= &clk_rpmh_clk8_a2.hw,
+	[RPMH_LN_BB_CLK3_A]	= &clk_rpmh_clk8_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,
+	[RPMH_RF_CLK4]		= &clk_rpmh_rf_clk4_a2.hw,
+	[RPMH_RF_CLK4_A]	= &clk_rpmh_rf_clk4_a2_ao.hw,
+	[RPMH_RF_CLK5]		= &clk_rpmh_rf_clk5_a2.hw,
+	[RPMH_RF_CLK5_A]	= &clk_rpmh_rf_clk5_a2_ao.hw,
+	[RPMH_IPA_CLK]		= &clk_rpmh_ipa.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_eliza = {
+	.clks = eliza_rpmh_clocks,
+	.num_clks = ARRAY_SIZE(eliza_rpmh_clocks),
+};
+
+static struct clk_hw *nord_rpmh_clocks[] = {
+	[RPMH_CXO_CLK]          = &clk_rpmh_bi_tcxo_div1.hw,
+	[RPMH_CXO_CLK_A]        = &clk_rpmh_bi_tcxo_div1_ao.hw,
+	[RPMH_LN_BB_CLK2]       = &clk_rpmh_ln_bb_clk2_a1.hw,
+	[RPMH_LN_BB_CLK2_A]     = &clk_rpmh_ln_bb_clk2_a1_ao.hw,
+	[RPMH_LN_BB_CLK3]       = &clk_rpmh_ln_bb_clk3_a1.hw,
+	[RPMH_LN_BB_CLK3_A]     = &clk_rpmh_ln_bb_clk3_a1_ao.hw,
+	[RPMH_IPA_CLK]          = &clk_rpmh_ipa.hw,
+};
+
+static const struct clk_rpmh_desc clk_rpmh_nord = {
+	.clks = nord_rpmh_clocks,
+	.num_clks = ARRAY_SIZE(nord_rpmh_clocks),
+};
+
 static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
 					 void *data)
 {
@@ -1029,9 +1073,11 @@ static int clk_rpmh_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id clk_rpmh_match_table[] = {
+	{ .compatible = "qcom,eliza-rpmh-clk", .data = &clk_rpmh_eliza},
 	{ .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur},
 	{ .compatible = "qcom,kaanapali-rpmh-clk", .data = &clk_rpmh_kaanapali},
 	{ .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos},
+	{ .compatible = "qcom,nord-rpmh-clk", .data = &clk_rpmh_nord},
 	{ .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},
diff --git a/drivers/clk/qcom/common.h b/drivers/clk/qcom/common.h
index 953c91f..6f2406f 100644
--- a/drivers/clk/qcom/common.h
+++ b/drivers/clk/qcom/common.h
@@ -28,7 +28,7 @@ struct qcom_icc_hws_data {
 struct qcom_cc_driver_data {
 	struct clk_alpha_pll **alpha_plls;
 	size_t num_alpha_plls;
-	u32 *clk_cbcrs;
+	const u32 *clk_cbcrs;
 	size_t num_clk_cbcrs;
 	const struct clk_rcg_dfs_data *dfs_rcgs;
 	size_t num_dfs_rcgs;
@@ -49,7 +49,7 @@ struct qcom_cc_desc {
 	size_t num_icc_hws;
 	unsigned int icc_first_node_id;
 	bool use_rpm;
-	struct qcom_cc_driver_data *driver_data;
+	const struct qcom_cc_driver_data *driver_data;
 };
 
 /**
diff --git a/drivers/clk/qcom/dispcc-eliza.c b/drivers/clk/qcom/dispcc-eliza.c
new file mode 100644
index 0000000..479f26e
--- /dev/null
+++ b/drivers/clk/qcom/dispcc-eliza.c
@@ -0,0 +1,2121 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023-2024, Linaro Ltd.
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,eliza-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 "clk-regmap-mux.h"
+#include "gdsc.h"
+#include "reset.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,
+	DT_HDMI_PHY_PLL_CLK,
+};
+
+#define DISP_CC_MISC_CMD	0xF000
+
+enum {
+	P_BI_TCXO,
+	P_DISP_CC_PLL0_OUT_MAIN,
+	P_DISP_CC_PLL1_OUT_EVEN,
+	P_DISP_CC_PLL1_OUT_MAIN,
+	P_DISP_CC_PLL2_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_HDMI_PHY_PLL_CLK,
+	P_SLEEP_CLK,
+};
+
+static const struct pll_vco lucid_ole_vco[] = {
+	{ 249600000, 2300000000, 0 },
+};
+
+static const struct pll_vco pongo_ole_vco[] = {
+	{ 38400000, 38400000, 0 },
+};
+
+static struct alpha_pll_config disp_cc_pll0_config = {
+	.l = 0xd,
+	.cal_l = 0x44,
+	.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,
+	.config = &disp_cc_pll0_config,
+	.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_lucid_evo_ops,
+		},
+	},
+};
+
+static struct alpha_pll_config disp_cc_pll1_config = {
+	.l = 0x1f,
+	.cal_l = 0x44,
+	.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,
+	.config = &disp_cc_pll1_config,
+	.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_lucid_evo_ops,
+		},
+	},
+};
+
+static const struct alpha_pll_config disp_cc_pll2_config = {
+	.l = 0x493,
+	.cal_l = 0x493,
+	.alpha = 0x0,
+	.config_ctl_val = 0x60000f6a,
+	.config_ctl_hi_val = 0x0001c808,
+	.config_ctl_hi1_val = 0x00000000,
+	.config_ctl_hi2_val = 0x04008174,
+	.test_ctl_val = 0x00000000,
+	.test_ctl_hi_val = 0x0080c496,
+	.test_ctl_hi1_val = 0x40100180,
+	.test_ctl_hi2_val = 0x441001bc,
+	.test_ctl_hi3_val = 0x000003d8,
+	.user_ctl_val = 0x00000000,
+	.user_ctl_hi_val = 0x00e50302,
+};
+
+static struct clk_alpha_pll disp_cc_pll2 = {
+	.offset = 0x2000,
+	.config = &disp_cc_pll2_config,
+	.vco_table = pongo_ole_vco,
+	.num_vco = ARRAY_SIZE(pongo_ole_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_PONGO_ELU],
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_pll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_SLEEP_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_pongo_elu_ops,
+		},
+	},
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0_ao[] = {
+	{ .index = DT_BI_TCXO_AO },
+};
+
+static const struct parent_map disp_cc_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_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_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ 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_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .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_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ 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_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_DSICLK, 1 },
+	{ P_DISP_CC_PLL2_OUT_MAIN, 2 },
+	{ P_DSI1_PHY_PLL_OUT_DSICLK, 3 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_DSI0_PHY_PLL_OUT_DSICLK },
+	{ .hw = &disp_cc_pll2.clkr.hw },
+	{ .index = DT_DSI1_PHY_PLL_OUT_DSICLK },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+	{ 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_5[] = {
+	{ .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_6[] = {
+	{ 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_6[] = {
+	{ .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_7[] = {
+	{ 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_7[] = {
+	{ .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_8[] = {
+	{ 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_8[] = {
+	{ .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_9[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISP_CC_PLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_9[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &disp_cc_pll0.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_10[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_HDMI_PHY_PLL_CLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_10[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_HDMI_PHY_PLL_CLK },
+};
+
+static const struct parent_map disp_cc_parent_map_11[] = {
+	{ 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_11[] = {
+	{ .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_12[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_DISP_CC_PLL2_OUT_MAIN, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_12[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &disp_cc_pll2.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_13[] = {
+	{ P_SLEEP_CLK, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_13_ao[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_disp_cc_esync0_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_esync0_clk_src = {
+	.cmd_rcgr = 0x80c0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_4,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_esync0_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_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_esync1_clk_src = {
+	.cmd_rcgr = 0x80d8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_4,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_esync1_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_byte2_ops,
+	},
+};
+
+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 = 0x8360,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_7,
+	.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_7,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_7),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+	.cmd_rcgr = 0x8180,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte0_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
+	.cmd_rcgr = 0x819c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_byte1_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = {
+	.cmd_rcgr = 0x8234,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_aux_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_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = {
+	.cmd_rcgr = 0x81e8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_8,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_link_clk_src",
+		.parent_data = disp_cc_parent_data_8,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_8),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_byte2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = {
+	.cmd_rcgr = 0x8204,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_5,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_pixel0_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = {
+	.cmd_rcgr = 0x821c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_5,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx0_pixel1_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = {
+	.cmd_rcgr = 0x8298,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_aux_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_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = {
+	.cmd_rcgr = 0x827c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_esync0_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 = 0x824c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_pixel0_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = {
+	.cmd_rcgr = 0x8264,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx1_pixel1_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = {
+	.cmd_rcgr = 0x82fc,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_aux_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_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = {
+	.cmd_rcgr = 0x82b0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_esync0_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 = 0x82cc,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_pixel0_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = {
+	.cmd_rcgr = 0x82e4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx2_pixel1_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = {
+	.cmd_rcgr = 0x8348,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_aux_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_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = {
+	.cmd_rcgr = 0x832c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_3,
+	.freq_tbl = ftbl_disp_cc_esync0_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 = 0x8314,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_2,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_dptx3_pixel0_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_dp_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+	.cmd_rcgr = 0x81b8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_6,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_esc0_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_esc1_clk_src = {
+	.cmd_rcgr = 0x81d0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_6,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_esc1_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_hdmi_app_clk_src = {
+	.cmd_rcgr = 0x83a8,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_9,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_hdmi_app_clk_src",
+		.parent_data = disp_cc_parent_data_9,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_9),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_hdmi_pclk_clk_src = {
+	.cmd_rcgr = 0x8390,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_10,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_hdmi_pclk_clk_src",
+		.parent_data = disp_cc_parent_data_10,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_10),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+	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(207000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(342000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(417000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(535000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	F(660000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+	.cmd_rcgr = 0x8150,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_11,
+	.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_11,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_11),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+	.cmd_rcgr = 0x8108,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk0_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
+	.cmd_rcgr = 0x8120,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk1_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = {
+	.cmd_rcgr = 0x8138,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_1,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_pclk2_clk_src",
+		.parent_data = disp_cc_parent_data_1,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
+		.ops = &clk_pixel_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+	.cmd_rcgr = 0x8168,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_vsync_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_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_disp_cc_osc_clk_src[] = {
+	F(38400000, P_DISP_CC_PLL2_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 disp_cc_osc_clk_src = {
+	.cmd_rcgr = 0x80f0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_12,
+	.freq_tbl = ftbl_disp_cc_osc_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_osc_clk_src",
+		.parent_data = disp_cc_parent_data_12,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_12),
+		.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 = 0xe064,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_13,
+	.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_13_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_13_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 disp_cc_xo_clk_src = {
+	.cmd_rcgr = 0xe044,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = disp_cc_parent_map_0,
+	.freq_tbl = ftbl_disp_cc_esync0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_xo_clk_src",
+		.parent_data = disp_cc_parent_data_0_ao,
+		.num_parents = ARRAY_SIZE(disp_cc_parent_data_0_ao),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+	.reg = 0x8198,
+	.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,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
+	.reg = 0x81b4,
+	.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,
+		.ops = &clk_regmap_div_ops,
+	},
+};
+
+static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = {
+	.reg = 0x8200,
+	.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 = 0x8294,
+	.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 = 0x82c8,
+	.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 = 0x8344,
+	.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_regmap_div disp_cc_mdss_hdmi_pclk_div_clk_src = {
+	.reg = 0x838c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "disp_cc_mdss_hdmi_pclk_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&disp_cc_mdss_hdmi_pclk_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch disp_cc_esync0_clk = {
+	.halt_reg = 0x80b8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_esync0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_esync0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_esync1_clk = {
+	.halt_reg = 0x80bc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_esync1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_esync1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_accu_shift_clk = {
+	.halt_reg = 0xe060,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xe060,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_accu_shift_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 = 0xa028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa028,
+		.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 = 0x80b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80b0,
+		.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 = 0x8034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8034,
+		.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 = 0x8038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8038,
+		.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 = 0x803c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x803c,
+		.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 = 0x8040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8040,
+		.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 = 0x8064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8064,
+		.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_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 = "disp_cc_mdss_dptx0_crypto_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_clk = {
+	.halt_reg = 0x804c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x804c,
+		.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 = 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_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 = 0x805c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x805c,
+		.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 = 0x8060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8060,
+		.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 = 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_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 = 0x8080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8080,
+		.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_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 = "disp_cc_mdss_dptx1_crypto_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_clk = {
+	.halt_reg = 0x8070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8070,
+		.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 = 0x8078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8078,
+		.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 = 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_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 = 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_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 = 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_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 = 0x8098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8098,
+		.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_crypto_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_dptx2_crypto_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_clk = {
+	.halt_reg = 0x808c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x808c,
+		.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 = 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_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 = 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_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 = 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_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_dptx3_aux_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_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_crypto_clk = {
+	.halt_reg = 0x80ac,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80ac,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_dptx3_crypto_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_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_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 = 0x80a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80a4,
+		.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 = 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_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 = 0x8044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8044,
+		.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 = 0x8048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8048,
+		.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_hdmi_ahbm_clk = {
+	.halt_reg = 0x8378,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8378,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_hdmi_ahbm_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_hdmi_app_clk = {
+	.halt_reg = 0x8388,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8388,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_hdmi_app_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_hdmi_app_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_hdmi_crypto_clk = {
+	.halt_reg = 0x8384,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8384,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_hdmi_crypto_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_hdmi_pclk_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_hdmi_intf_clk = {
+	.halt_reg = 0x8380,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8380,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_hdmi_intf_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_hdmi_pclk_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_hdmi_pclk_clk = {
+	.halt_reg = 0x837c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x837c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_mdss_hdmi_pclk_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_hdmi_pclk_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 = 0x8010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8010,
+		.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_aon_ops,
+		},
+	},
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut1_clk = {
+	.halt_reg = 0xa014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa014,
+		.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 = 0x8020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x8020,
+		.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_pclk2_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_pclk2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_mdss_pclk2_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 = 0xa024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa024,
+		.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 = 0x8030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x8030,
+		.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 clk_branch disp_cc_osc_clk = {
+	.halt_reg = 0x80b4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x80b4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "disp_cc_osc_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&disp_cc_osc_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 = POLL_CFG_GDSCR | 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 = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *disp_cc_eliza_clocks[] = {
+	[DISP_CC_ESYNC0_CLK] = &disp_cc_esync0_clk.clkr,
+	[DISP_CC_ESYNC0_CLK_SRC] = &disp_cc_esync0_clk_src.clkr,
+	[DISP_CC_ESYNC1_CLK] = &disp_cc_esync1_clk.clkr,
+	[DISP_CC_ESYNC1_CLK_SRC] = &disp_cc_esync1_clk_src.clkr,
+	[DISP_CC_MDSS_ACCU_SHIFT_CLK] = &disp_cc_mdss_accu_shift_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_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.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_CRYPTO_CLK] = &disp_cc_mdss_dptx1_crypto_clk.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_CRYPTO_CLK] = &disp_cc_mdss_dptx2_crypto_clk.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_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_CRYPTO_CLK] = &disp_cc_mdss_dptx3_crypto_clk.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_HDMI_AHBM_CLK] = &disp_cc_mdss_hdmi_ahbm_clk.clkr,
+	[DISP_CC_MDSS_HDMI_APP_CLK] = &disp_cc_mdss_hdmi_app_clk.clkr,
+	[DISP_CC_MDSS_HDMI_APP_CLK_SRC] = &disp_cc_mdss_hdmi_app_clk_src.clkr,
+	[DISP_CC_MDSS_HDMI_CRYPTO_CLK] = &disp_cc_mdss_hdmi_crypto_clk.clkr,
+	[DISP_CC_MDSS_HDMI_INTF_CLK] = &disp_cc_mdss_hdmi_intf_clk.clkr,
+	[DISP_CC_MDSS_HDMI_PCLK_CLK] = &disp_cc_mdss_hdmi_pclk_clk.clkr,
+	[DISP_CC_MDSS_HDMI_PCLK_CLK_SRC] = &disp_cc_mdss_hdmi_pclk_clk_src.clkr,
+	[DISP_CC_MDSS_HDMI_PCLK_DIV_CLK_SRC] = &disp_cc_mdss_hdmi_pclk_div_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_PCLK2_CLK] = &disp_cc_mdss_pclk2_clk.clkr,
+	[DISP_CC_MDSS_PCLK2_CLK_SRC] = &disp_cc_mdss_pclk2_clk_src.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_OSC_CLK] = &disp_cc_osc_clk.clkr,
+	[DISP_CC_OSC_CLK_SRC] = &disp_cc_osc_clk_src.clkr,
+	[DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+	[DISP_CC_PLL1] = &disp_cc_pll1.clkr,
+	[DISP_CC_PLL2] = &disp_cc_pll2.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_eliza_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_eliza_gdscs[] = {
+	[MDSS_GDSC] = &mdss_gdsc,
+	[MDSS_INT2_GDSC] = &mdss_int2_gdsc,
+};
+
+static const struct regmap_config disp_cc_eliza_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xf004, /* 0x10000, 0x10004 and maybe others are for TZ */
+	.fast_io = true,
+};
+
+static struct clk_alpha_pll *disp_cc_eliza_plls[] = {
+	&disp_cc_pll0,
+	&disp_cc_pll1,
+	&disp_cc_pll2,
+};
+
+static const u32 disp_cc_eliza_critical_cbcrs[] = {
+	0xe07c, /* DISP_CC_SLEEP_CLK */
+	0xe05c, /* DISP_CC_XO_CLK */
+	0xc00c, /* DISP_CC_MDSS_RSCC_AHB_CLK */
+	0xc008, /* DISP_CC_MDSS_RSCC_VSYNC_CLK */
+};
+
+static void clk_eliza_regs_configure(struct device *dev, struct regmap *regmap)
+{
+	/* Enable clock gating for MDP clocks */
+	regmap_set_bits(regmap, DISP_CC_MISC_CMD, BIT(4));
+}
+
+static const struct qcom_cc_driver_data disp_cc_eliza_driver_data = {
+	.alpha_plls = disp_cc_eliza_plls,
+	.num_alpha_plls = ARRAY_SIZE(disp_cc_eliza_plls),
+	.clk_cbcrs = disp_cc_eliza_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(disp_cc_eliza_critical_cbcrs),
+	.clk_regs_configure = clk_eliza_regs_configure,
+};
+
+static const struct qcom_cc_desc disp_cc_eliza_desc = {
+	.config = &disp_cc_eliza_regmap_config,
+	.clks = disp_cc_eliza_clocks,
+	.num_clks = ARRAY_SIZE(disp_cc_eliza_clocks),
+	.resets = disp_cc_eliza_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_eliza_resets),
+	.gdscs = disp_cc_eliza_gdscs,
+	.num_gdscs = ARRAY_SIZE(disp_cc_eliza_gdscs),
+	.use_rpm = true,
+	.driver_data = &disp_cc_eliza_driver_data,
+};
+
+static const struct of_device_id disp_cc_eliza_match_table[] = {
+	{ .compatible = "qcom,eliza-dispcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_eliza_match_table);
+
+static int disp_cc_eliza_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &disp_cc_eliza_desc);
+}
+
+static struct platform_driver disp_cc_eliza_driver = {
+	.probe = disp_cc_eliza_probe,
+	.driver = {
+		.name = "dispcc-eliza",
+		.of_match_table = disp_cc_eliza_match_table,
+	},
+};
+
+module_platform_driver(disp_cc_eliza_driver);
+
+MODULE_DESCRIPTION("QTI DISPCC Eliza Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/dispcc-glymur.c b/drivers/clk/qcom/dispcc-glymur.c
index 5203fa6..c4bb328 100644
--- a/drivers/clk/qcom/dispcc-glymur.c
+++ b/drivers/clk/qcom/dispcc-glymur.c
@@ -6,9 +6,7 @@
 #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/pm_runtime.h>
 #include <linux/regmap.h>
 
 #include <dt-bindings/clock/qcom,glymur-dispcc.h>
@@ -417,7 +415,7 @@ static struct clk_rcg2 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_dp_ops,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
@@ -747,7 +745,6 @@ static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -762,7 +759,6 @@ static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
 			&disp_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -1925,7 +1921,7 @@ static struct clk_alpha_pll *disp_cc_glymur_plls[] = {
 	&disp_cc_pll1,
 };
 
-static u32 disp_cc_glymur_critical_cbcrs[] = {
+static const u32 disp_cc_glymur_critical_cbcrs[] = {
 	0xe07c, /* DISP_CC_SLEEP_CLK */
 	0xe05c, /* DISP_CC_XO_CLK */
 };
@@ -1938,7 +1934,7 @@ static const struct regmap_config disp_cc_glymur_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data disp_cc_glymur_driver_data = {
+static const struct qcom_cc_driver_data disp_cc_glymur_driver_data = {
 	.alpha_plls = disp_cc_glymur_plls,
 	.num_alpha_plls = ARRAY_SIZE(disp_cc_glymur_plls),
 	.clk_cbcrs = disp_cc_glymur_critical_cbcrs,
@@ -1978,5 +1974,5 @@ static struct platform_driver disp_cc_glymur_driver = {
 
 module_platform_driver(disp_cc_glymur_driver);
 
-MODULE_DESCRIPTION("QTI DISPCC GLYMUR Driver");
+MODULE_DESCRIPTION("QTI DISPCC Glymur Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/dispcc-kaanapali.c b/drivers/clk/qcom/dispcc-kaanapali.c
index baae2ec..42912c6 100644
--- a/drivers/clk/qcom/dispcc-kaanapali.c
+++ b/drivers/clk/qcom/dispcc-kaanapali.c
@@ -6,9 +6,7 @@
 #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/pm_runtime.h>
 #include <linux/regmap.h>
 
 #include <dt-bindings/clock/qcom,kaanapali-dispcc.h>
@@ -800,7 +798,6 @@ static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -815,7 +812,6 @@ static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = {
 			&disp_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -1890,7 +1886,7 @@ static struct clk_alpha_pll *disp_cc_kaanapali_plls[] = {
 	&disp_cc_pll2,
 };
 
-static u32 disp_cc_kaanapali_critical_cbcrs[] = {
+static const u32 disp_cc_kaanapali_critical_cbcrs[] = {
 	0xe064, /* DISP_CC_SLEEP_CLK */
 	0xe05c, /* DISP_CC_XO_CLK */
 	0xc00c, /* DISP_CC_MDSS_RSCC_AHB_CLK */
@@ -1911,7 +1907,7 @@ static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regm
 	regmap_update_bits(regmap, DISP_CC_MISC_CMD, BIT(4), BIT(4));
 }
 
-static struct qcom_cc_driver_data disp_cc_kaanapali_driver_data = {
+static const struct qcom_cc_driver_data disp_cc_kaanapali_driver_data = {
 	.alpha_plls = disp_cc_kaanapali_plls,
 	.num_alpha_plls = ARRAY_SIZE(disp_cc_kaanapali_plls),
 	.clk_cbcrs = disp_cc_kaanapali_critical_cbcrs,
diff --git a/drivers/clk/qcom/dispcc-milos.c b/drivers/clk/qcom/dispcc-milos.c
index 95b6dd8..dfffb6d 100644
--- a/drivers/clk/qcom/dispcc-milos.c
+++ b/drivers/clk/qcom/dispcc-milos.c
@@ -4,12 +4,10 @@
  * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
  */
 
-#include <linux/clk.h>
 #include <linux/clk-provider.h>
-#include <linux/err.h>
 #include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
@@ -394,7 +392,6 @@ static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -909,7 +906,7 @@ static struct clk_alpha_pll *disp_cc_milos_plls[] = {
 	&disp_cc_pll0,
 };
 
-static u32 disp_cc_milos_critical_cbcrs[] = {
+static const u32 disp_cc_milos_critical_cbcrs[] = {
 	0xe06c, /* DISP_CC_SLEEP_CLK */
 	0xe04c, /* DISP_CC_XO_CLK */
 };
@@ -929,7 +926,7 @@ static void disp_cc_milos_clk_regs_configure(struct device *dev, struct regmap *
 }
 
 
-static struct qcom_cc_driver_data disp_cc_milos_driver_data = {
+static const struct qcom_cc_driver_data disp_cc_milos_driver_data = {
 	.alpha_plls = disp_cc_milos_plls,
 	.num_alpha_plls = ARRAY_SIZE(disp_cc_milos_plls),
 	.clk_cbcrs = disp_cc_milos_critical_cbcrs,
diff --git a/drivers/clk/qcom/dispcc-qcs615.c b/drivers/clk/qcom/dispcc-qcs615.c
index 4a6d784..637698e6 100644
--- a/drivers/clk/qcom/dispcc-qcs615.c
+++ b/drivers/clk/qcom/dispcc-qcs615.c
@@ -739,7 +739,7 @@ static struct clk_alpha_pll *disp_cc_qcs615_plls[] = {
 	&disp_cc_pll0,
 };
 
-static u32 disp_cc_qcs615_critical_cbcrs[] = {
+static const u32 disp_cc_qcs615_critical_cbcrs[] = {
 	0x6054, /* DISP_CC_XO_CLK */
 };
 
@@ -751,7 +751,7 @@ static const struct regmap_config disp_cc_qcs615_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data disp_cc_qcs615_driver_data = {
+static const struct qcom_cc_driver_data disp_cc_qcs615_driver_data = {
 	.alpha_plls = disp_cc_qcs615_plls,
 	.num_alpha_plls = ARRAY_SIZE(disp_cc_qcs615_plls),
 	.clk_cbcrs = disp_cc_qcs615_critical_cbcrs,
diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c
index ab1a8d4..d7e37fb 100644
--- a/drivers/clk/qcom/dispcc-sc7180.c
+++ b/drivers/clk/qcom/dispcc-sc7180.c
@@ -17,6 +17,7 @@
 #include "clk-regmap-divider.h"
 #include "common.h"
 #include "gdsc.h"
+#include "reset.h"
 
 enum {
 	P_BI_TCXO,
@@ -636,6 +637,11 @@ static struct gdsc mdss_gdsc = {
 	.flags = HW_CTRL,
 };
 
+static const struct qcom_reset_map disp_cc_sc7180_resets[] = {
+	[DISP_CC_MDSS_CORE_BCR] = { 0x2000 },
+	[DISP_CC_MDSS_RSCC_BCR] = { 0x4000 },
+};
+
 static struct gdsc *disp_cc_sc7180_gdscs[] = {
 	[MDSS_GDSC] = &mdss_gdsc,
 };
@@ -687,6 +693,8 @@ static const struct qcom_cc_desc disp_cc_sc7180_desc = {
 	.config = &disp_cc_sc7180_regmap_config,
 	.clks = disp_cc_sc7180_clocks,
 	.num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks),
+	.resets = disp_cc_sc7180_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_sc7180_resets),
 	.gdscs = disp_cc_sc7180_gdscs,
 	.num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs),
 };
diff --git a/drivers/clk/qcom/dispcc-sc8280xp.c b/drivers/clk/qcom/dispcc-sc8280xp.c
index 5903a75..e91dfed 100644
--- a/drivers/clk/qcom/dispcc-sc8280xp.c
+++ b/drivers/clk/qcom/dispcc-sc8280xp.c
@@ -1160,7 +1160,6 @@ static struct clk_regmap_div disp0_cc_mdss_byte0_div_clk_src = {
 			&disp0_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -1175,7 +1174,6 @@ static struct clk_regmap_div disp1_cc_mdss_byte0_div_clk_src = {
 			&disp1_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -1190,7 +1188,6 @@ static struct clk_regmap_div disp0_cc_mdss_byte1_div_clk_src = {
 			&disp0_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -1205,7 +1202,6 @@ static struct clk_regmap_div disp1_cc_mdss_byte1_div_clk_src = {
 			&disp1_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
diff --git a/drivers/clk/qcom/dispcc-sm4450.c b/drivers/clk/qcom/dispcc-sm4450.c
index e8752d0..2fdacc26 100644
--- a/drivers/clk/qcom/dispcc-sm4450.c
+++ b/drivers/clk/qcom/dispcc-sm4450.c
@@ -335,7 +335,6 @@ static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
 			&disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
diff --git a/drivers/clk/qcom/dispcc-sm6115.c b/drivers/clk/qcom/dispcc-sm6115.c
index 8ae25d5..75bd5721 100644
--- a/drivers/clk/qcom/dispcc-sm6115.c
+++ b/drivers/clk/qcom/dispcc-sm6115.c
@@ -22,6 +22,7 @@
 #include "clk-regmap-divider.h"
 #include "common.h"
 #include "gdsc.h"
+#include "reset.h"
 
 enum {
 	DT_BI_TCXO,
@@ -511,6 +512,10 @@ static struct clk_branch disp_cc_sleep_clk = {
 	},
 };
 
+static const struct qcom_reset_map disp_cc_sm6115_resets[] = {
+	[DISP_CC_MDSS_CORE_BCR] = { 0x2000 },
+};
+
 static struct gdsc mdss_gdsc = {
 	.gdscr = 0x3000,
 	.pd = {
@@ -561,6 +566,8 @@ static const struct qcom_cc_desc disp_cc_sm6115_desc = {
 	.config = &disp_cc_sm6115_regmap_config,
 	.clks = disp_cc_sm6115_clocks,
 	.num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks),
+	.resets = disp_cc_sm6115_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_sm6115_resets),
 	.gdscs = disp_cc_sm6115_gdscs,
 	.num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs),
 };
diff --git a/drivers/clk/qcom/dispcc-sm6125.c b/drivers/clk/qcom/dispcc-sm6125.c
index 851d38a..2c67abc 100644
--- a/drivers/clk/qcom/dispcc-sm6125.c
+++ b/drivers/clk/qcom/dispcc-sm6125.c
@@ -17,6 +17,7 @@
 #include "clk-regmap.h"
 #include "common.h"
 #include "gdsc.h"
+#include "reset.h"
 
 enum {
 	P_BI_TCXO,
@@ -607,6 +608,10 @@ static struct clk_branch disp_cc_xo_clk = {
 	},
 };
 
+static const struct qcom_reset_map disp_cc_sm6125_resets[] = {
+	[DISP_CC_MDSS_CORE_BCR] = { 0x2000 },
+};
+
 static struct gdsc mdss_gdsc = {
 	.gdscr = 0x3000,
 	.pd = {
@@ -663,6 +668,8 @@ static const struct qcom_cc_desc disp_cc_sm6125_desc = {
 	.config = &disp_cc_sm6125_regmap_config,
 	.clks = disp_cc_sm6125_clocks,
 	.num_clks = ARRAY_SIZE(disp_cc_sm6125_clocks),
+	.resets = disp_cc_sm6125_resets,
+	.num_resets = ARRAY_SIZE(disp_cc_sm6125_resets),
 	.gdscs = disp_cc_sm6125_gdscs,
 	.num_gdscs = ARRAY_SIZE(disp_cc_sm6125_gdscs),
 };
diff --git a/drivers/clk/qcom/dispcc-sm8250.c b/drivers/clk/qcom/dispcc-sm8250.c
index 8f433e1..e59cdad 100644
--- a/drivers/clk/qcom/dispcc-sm8250.c
+++ b/drivers/clk/qcom/dispcc-sm8250.c
@@ -578,7 +578,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
 		.name = "disp_cc_mdss_pclk0_clk_src",
 		.parent_data = disp_cc_parent_data_6,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
-		.flags = CLK_SET_RATE_PARENT,
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
 		.ops = &clk_pixel_ops,
 	},
 };
@@ -592,7 +592,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = {
 		.name = "disp_cc_mdss_pclk1_clk_src",
 		.parent_data = disp_cc_parent_data_6,
 		.num_parents = ARRAY_SIZE(disp_cc_parent_data_6),
-		.flags = CLK_SET_RATE_PARENT,
+		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
 		.ops = &clk_pixel_ops,
 	},
 };
@@ -632,7 +632,7 @@ static struct clk_rcg2 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,
+		.ops = &clk_rcg2_shared_ops,
 	},
 };
 
diff --git a/drivers/clk/qcom/dispcc-sm8450.c b/drivers/clk/qcom/dispcc-sm8450.c
index 9ce9fd2..2e91332 100644
--- a/drivers/clk/qcom/dispcc-sm8450.c
+++ b/drivers/clk/qcom/dispcc-sm8450.c
@@ -409,7 +409,7 @@ static struct clk_rcg2 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_dp_ops,
+		.ops = &clk_rcg2_ops,
 	},
 };
 
diff --git a/drivers/clk/qcom/dispcc0-sa8775p.c b/drivers/clk/qcom/dispcc0-sa8775p.c
index aeda9cf..b248fa9 100644
--- a/drivers/clk/qcom/dispcc0-sa8775p.c
+++ b/drivers/clk/qcom/dispcc0-sa8775p.c
@@ -591,7 +591,6 @@ static struct clk_regmap_div mdss_0_disp_cc_mdss_byte0_div_clk_src = {
 			&mdss_0_disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -606,7 +605,6 @@ static struct clk_regmap_div mdss_0_disp_cc_mdss_byte1_div_clk_src = {
 			&mdss_0_disp_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
diff --git a/drivers/clk/qcom/dispcc1-sa8775p.c b/drivers/clk/qcom/dispcc1-sa8775p.c
index cd55d1c..9882edb 100644
--- a/drivers/clk/qcom/dispcc1-sa8775p.c
+++ b/drivers/clk/qcom/dispcc1-sa8775p.c
@@ -591,7 +591,6 @@ static struct clk_regmap_div mdss_1_disp_cc_mdss_byte0_div_clk_src = {
 			&mdss_1_disp_cc_mdss_byte0_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
@@ -606,7 +605,6 @@ static struct clk_regmap_div mdss_1_disp_cc_mdss_byte1_div_clk_src = {
 			&mdss_1_disp_cc_mdss_byte1_clk_src.clkr.hw,
 		},
 		.num_parents = 1,
-		.flags = CLK_SET_RATE_PARENT,
 		.ops = &clk_regmap_div_ops,
 	},
 };
diff --git a/drivers/clk/qcom/gcc-eliza.c b/drivers/clk/qcom/gcc-eliza.c
new file mode 100644
index 0000000..24c3aae08
--- /dev/null
+++ b/drivers/clk/qcom/gcc-eliza.c
@@ -0,0 +1,3105 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,eliza-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_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_PIPE_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GCC_GPLL0_OUT_EVEN,
+	P_GCC_GPLL0_OUT_MAIN,
+	P_GCC_GPLL4_OUT_MAIN,
+	P_GCC_GPLL7_OUT_MAIN,
+	P_GCC_GPLL8_OUT_MAIN,
+	P_GCC_GPLL9_OUT_MAIN,
+	P_PCIE_0_PIPE_CLK,
+	P_PCIE_1_PIPE_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_PIPE_CLK,
+};
+
+static struct clk_alpha_pll gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x52020,
+		.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_ole_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_OLE],
+	.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_ole_ops,
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll4 = {
+	.offset = 0x4000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x52020,
+		.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_ole_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll7 = {
+	.offset = 0x7000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x52020,
+		.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_ole_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll8 = {
+	.offset = 0x8000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x52020,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpll8",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll gcc_gpll9 = {
+	.offset = 0x9000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x52020,
+		.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_ole_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_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_2[] = {
+	{ .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_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 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL7_OUT_MAIN, 2 },
+	{ 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_gpll7.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL8_OUT_MAIN, 2 },
+	{ P_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+	{ .hw = &gcc_gpll8.clkr.hw },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+	{ 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_7[] = {
+	{ .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_8[] = {
+	{ P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+	{ P_GCC_GPLL0_OUT_EVEN, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+	{ .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK },
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0_out_even.clkr.hw },
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = {
+	.reg = 0x6b080,
+	.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_phy_mux gcc_pcie_1_pipe_clk_src = {
+	.reg = 0xac07c,
+	.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_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = {
+	.reg = 0x77068,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_0_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_RX_SYMBOL_0_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = {
+	.reg = 0x770ec,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_rx_symbol_1_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_RX_SYMBOL_1_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = {
+	.reg = 0x77058,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ufs_phy_tx_symbol_0_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_TX_SYMBOL_0_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = {
+	.reg = 0x39070,
+	.shift = 0,
+	.width = 2,
+	.parent_map = gcc_parent_map_8,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb3_prim_phy_pipe_clk_src",
+			.parent_data = gcc_parent_data_8,
+			.num_parents = ARRAY_SIZE(gcc_parent_data_8),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+	F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+	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 = 0x64004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0x65004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0x66004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.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 const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_0_aux_clk_src = {
+	.cmd_rcgr = 0x6b084,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.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),
+		.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_EVEN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x6b068,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0xac080,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_1_aux_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_pcie_1_phy_rchng_clk_src = {
+	.cmd_rcgr = 0xac064,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0x33010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pdm2_clk_src,
+	.hw_clk_ctrl = true,
+	.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_wrap1_qspi_ref_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	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(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+	F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+	F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+	F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0),
+	F(250000000, P_GCC_GPLL7_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap1_qspi_ref_clk_src_init = {
+	.name = "gcc_qupv3_wrap1_qspi_ref_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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_qspi_ref_clk_src = {
+	.cmd_rcgr = 0x188c0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap1_qspi_ref_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap1_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	F(61440000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 625),
+	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(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+	F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+	F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+	F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
+	.cmd_rcgr = 0x18014,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
+	.cmd_rcgr = 0x18150,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s3_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	F(61440000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 625),
+	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),
+	{ }
+};
+
+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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
+	.cmd_rcgr = 0x182a0,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.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_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
+	.cmd_rcgr = 0x183dc,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s5_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	F(61440000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 625),
+	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(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+	F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+	F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+	F(128000000, P_GCC_GPLL0_OUT_MAIN, 1, 16, 75),
+	{ }
+};
+
+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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
+	.cmd_rcgr = 0x18518,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s5_clk_src,
+	.hw_clk_ctrl = true,
+	.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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
+	.cmd_rcgr = 0x18654,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
+	.cmd_rcgr = 0x18790,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap1_s7_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_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = {
+	.cmd_rcgr = 0x1e014,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.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_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = {
+	.cmd_rcgr = 0x1e150,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_gcc_qupv3_wrap2_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	F(61440000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 625),
+	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(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+	F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+	F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+	F(125000000, P_GCC_GPLL7_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s2_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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = {
+	.cmd_rcgr = 0x1e28c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.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_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = {
+	.cmd_rcgr = 0x1e3c8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.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_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = {
+	.cmd_rcgr = 0x1e504,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.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_parent_data_0,
+	.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = {
+	.cmd_rcgr = 0x1e640,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s5_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap2_s5_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s6_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_s6_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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = {
+	.cmd_rcgr = 0x1e77c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap2_s6_clk_src_init,
+};
+
+static struct clk_init_data gcc_qupv3_wrap2_s7_clk_src_init = {
+	.name = "gcc_qupv3_wrap2_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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
+	.cmd_rcgr = 0x1e8b8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap1_s3_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap2_s7_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_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_GPLL8_OUT_MAIN, 2, 0, 0),
+	F(384000000, P_GCC_GPLL8_OUT_MAIN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+	.cmd_rcgr = 0xa9018,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_5,
+	.freq_tbl = ftbl_gcc_sdcc1_apps_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_apps_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_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+	F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+	F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0),
+	F(300000000, P_GCC_GPLL0_OUT_EVEN, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+	.cmd_rcgr = 0xa9040,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_5,
+	.freq_tbl = ftbl_gcc_sdcc1_ice_core_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc1_ice_core_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_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
+	F(400000, P_BI_TCXO, 12, 1, 4),
+	F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
+	F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0),
+	F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
+	F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+	F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
+	.cmd_rcgr = 0x1401c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_7,
+	.freq_tbl = ftbl_gcc_sdcc2_apps_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sdcc2_apps_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_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(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+	F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0),
+	F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = {
+	.cmd_rcgr = 0x77034,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_axi_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_no_init_park_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = {
+	F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
+	F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0),
+	F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = {
+	.cmd_rcgr = 0x7708c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_ice_core_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_no_init_park_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = {
+	F(9600000, P_BI_TCXO, 2, 0, 0),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = {
+	.cmd_rcgr = 0x770c0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_6,
+	.freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_phy_aux_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_no_init_park_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = {
+	.cmd_rcgr = 0x770a4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_ufs_phy_unipro_core_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_no_init_park_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = {
+	F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0),
+	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 = 0x39030,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb30_prim_master_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0x39048,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.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 = 0x39074,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_0_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.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),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_pcie_0_pipe_div2_clk_src = {
+	.reg = 0x6b0a4,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_0_pipe_div2_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_div2_clk_src = {
+	.reg = 0xac0a0,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_1_pipe_div2_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_wrap1_s2_clk_src = {
+	.reg = 0x1828c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap1_s2_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_qupv3_wrap1_qspi_ref_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 = 0x39060,
+	.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_pcie_axi_clk = {
+	.halt_reg = 0x10068,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x10068,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(30),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_aggre_noc_pcie_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
+	.halt_reg = 0x770f4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x770f4,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x770f4,
+		.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_usb3_prim_axi_clk = {
+	.halt_reg = 0x39094,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x39094,
+		.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_boot_rom_ahb_clk = {
+	.halt_reg = 0x38004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x38004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.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 = 0x26014,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x26014,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x26014,
+		.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 = 0x26024,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x26024,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x26024,
+		.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_cfg_noc_pcie_anoc_ahb_clk = {
+	.halt_reg = 0x10050,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x10050,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cfg_noc_pcie_anoc_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = {
+	.halt_reg = 0x39090,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x39090,
+		.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_cnoc_pcie_sf_axi_clk = {
+	.halt_reg = 0x10058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x10058,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cnoc_pcie_sf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_ddrss_gpu_axi_clk = {
+	.halt_reg = 0x71158,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x71158,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x71158,
+		.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_ddrss_pcie_sf_qtb_clk = {
+	.halt_reg = 0x1007c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1007c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_ddrss_pcie_sf_qtb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_disp_hf_axi_clk = {
+	.halt_reg = 0x27008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x27008,
+		.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_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_gemnoc_gfx_clk = {
+	.halt_reg = 0x71010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x71010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x71010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gemnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gpu_gpll0_cph_clk_src = {
+	.halt_reg = 0x71150,
+	.halt_check = BRANCH_HALT_ENABLE_VOTED,
+	.clkr = {
+		.enable_reg = 0x71150,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_cph_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_cph_clk_src = {
+	.halt_reg = 0x71154,
+	.halt_check = BRANCH_HALT_ENABLE_VOTED,
+	.clkr = {
+		.enable_reg = 0x71154,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_gpll0_div_cph_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_smmu_vote_clk = {
+	.halt_reg = 0x7d000,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7d000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gpu_smmu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_mmu_tcu_vote_clk = {
+	.halt_reg = 0x7d02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7d02c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_mmu_tcu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_0_aux_clk = {
+	.halt_reg = 0x6b044,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x6b040,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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_mstr_axi_clk = {
+	.halt_reg = 0x6b030,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x6b030,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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_phy_rchng_clk = {
+	.halt_reg = 0x6b064,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(22),
+		.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 = 0x6b054,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.enable_mask = BIT(4),
+		.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_pipe_div2_clk = {
+	.halt_reg = 0x6b0a8,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x52018,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_0_pipe_div2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_0_pipe_div2_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 = 0x6b020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b020,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x6b01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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_1_aux_clk = {
+	.halt_reg = 0xac040,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(29),
+		.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 = 0xac03c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xac03c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(28),
+		.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 = 0xac02c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0xac02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(27),
+		.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_rchng_clk = {
+	.halt_reg = 0xac060,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(24),
+		.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 = 0xac050,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(23),
+		.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_pipe_div2_clk = {
+	.halt_reg = 0xac0a4,
+	.halt_check = BRANCH_HALT_SKIP,
+	.clkr = {
+		.enable_reg = 0x52018,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_pipe_div2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_1_pipe_div2_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 = 0xac01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xac01c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(26),
+		.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 = 0xac018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_1_slv_q2a_axi_clk",
+			.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_VOTED,
+	.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_qmip_camera_cmd_ahb_clk = {
+	.halt_reg = 0x26010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x26010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x26010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_camera_cmd_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = {
+	.halt_reg = 0x26008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x26008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x26008,
+		.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 = 0x2600c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2600c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2600c,
+		.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_gpu_ahb_clk = {
+	.halt_reg = 0x71008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x71008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x71008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_gpu_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_pcie_ahb_clk = {
+	.halt_reg = 0x6b018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x6b018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52000,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_pcie_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_v_cpu_ahb_clk = {
+	.halt_reg = 0x32010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x32010,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x32010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qmip_video_v_cpu_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qmip_video_vcodec_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_video_vcodec_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = {
+	.halt_reg = 0x2301c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x23008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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_qspi_ref_clk = {
+	.halt_reg = 0x188bc,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(29),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap1_qspi_ref_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap1_s0_clk = {
+	.halt_reg = 0x18004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x18140,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x1827c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x18290,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x183cc,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x18508,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x18644,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.enable_mask = BIT(28),
+		.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 = 0x18780,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(16),
+		.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_wrap2_core_2x_clk = {
+	.halt_reg = 0x23174,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_core_clk = {
+	.halt_reg = 0x23160,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s0_clk = {
+	.halt_reg = 0x1e004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s1_clk = {
+	.halt_reg = 0x1e140,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s2_clk = {
+	.halt_reg = 0x1e27c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s3_clk = {
+	.halt_reg = 0x1e3b8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s4_clk = {
+	.halt_reg = 0x1e4f4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s5_clk = {
+	.halt_reg = 0x1e630,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s6_clk = {
+	.halt_reg = 0x1e76c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap2_s7_clk = {
+	.halt_reg = 0x1e8a8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(17),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap2_s7_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap2_s7_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_1_m_ahb_clk = {
+	.halt_reg = 0x23000,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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 = 0x23004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52008,
+		.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_2_m_ahb_clk = {
+	.halt_reg = 0x23158,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23158,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_2_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = {
+	.halt_reg = 0x2315c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2315c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52010,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_2_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+	.halt_reg = 0xa9004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa9004,
+		.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 = 0xa9008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0xa9008,
+		.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 = 0xa9030,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0xa9030,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0xa9030,
+		.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 = 0x14014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x14014,
+		.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_ufs_phy_ahb_clk = {
+	.halt_reg = 0x77028,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x77028,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77028,
+		.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 = 0x77018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x77018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x77018,
+		.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 = 0x7707c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7707c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7707c,
+		.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 = 0x770bc,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x770bc,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x770bc,
+		.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 = 0x77030,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x77030,
+		.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 = 0x770d8,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x770d8,
+		.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 = 0x7702c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x7702c,
+		.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 = 0x7706c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x7706c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x7706c,
+		.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_usb30_prim_atb_clk = {
+	.halt_reg = 0x3908c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x3908c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb30_prim_atb_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_master_clk = {
+	.halt_reg = 0x39018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x39018,
+		.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 = 0x3902c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3902c,
+		.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 = 0x39028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x39028,
+		.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 = 0x39064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x39064,
+		.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 = 0x39068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x39068,
+		.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 = 0x3906c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.hwcg_reg = 0x3906c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3906c,
+		.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_video_axi0_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_video_axi0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_video_axi1_clk = {
+	.halt_reg = 0x32028,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x32028,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x32028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_video_axi1_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gcc_pcie_0_gdsc = {
+	.gdscr = 0x6b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x5214c,
+	.collapse_mask = BIT(0),
+	.pd = {
+		.name = "gcc_pcie_0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_0_phy_gdsc = {
+	.gdscr = 0x6c000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x5214c,
+	.collapse_mask = BIT(2),
+	.pd = {
+		.name = "gcc_pcie_0_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_1_gdsc = {
+	.gdscr = 0xac004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x5214c,
+	.collapse_mask = BIT(3),
+	.pd = {
+		.name = "gcc_pcie_1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_1_phy_gdsc = {
+	.gdscr = 0xad000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x5214c,
+	.collapse_mask = BIT(4),
+	.pd = {
+		.name = "gcc_pcie_1_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_ufs_mem_phy_gdsc = {
+	.gdscr = 0x9e000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "gcc_ufs_mem_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+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",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gcc_usb30_prim_gdsc = {
+	.gdscr = 0x39004,
+	.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 = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc gcc_usb3_phy_gdsc = {
+	.gdscr = 0x50018,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "gcc_usb3_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *gcc_eliza_clocks[] = {
+	[GCC_AGGRE_NOC_PCIE_AXI_CLK] = &gcc_aggre_noc_pcie_axi_clk.clkr,
+	[GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr,
+	[GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_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_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr,
+	[GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr,
+	[GCC_CNOC_PCIE_SF_AXI_CLK] = &gcc_cnoc_pcie_sf_axi_clk.clkr,
+	[GCC_DDRSS_GPU_AXI_CLK] = &gcc_ddrss_gpu_axi_clk.clkr,
+	[GCC_DDRSS_PCIE_SF_QTB_CLK] = &gcc_ddrss_pcie_sf_qtb_clk.clkr,
+	[GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_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_GPLL0] = &gcc_gpll0.clkr,
+	[GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr,
+	[GCC_GPLL4] = &gcc_gpll4.clkr,
+	[GCC_GPLL7] = &gcc_gpll7.clkr,
+	[GCC_GPLL8] = &gcc_gpll8.clkr,
+	[GCC_GPLL9] = &gcc_gpll9.clkr,
+	[GCC_GPU_GEMNOC_GFX_CLK] = &gcc_gpu_gemnoc_gfx_clk.clkr,
+	[GCC_GPU_GPLL0_CPH_CLK_SRC] = &gcc_gpu_gpll0_cph_clk_src.clkr,
+	[GCC_GPU_GPLL0_DIV_CPH_CLK_SRC] = &gcc_gpu_gpll0_div_cph_clk_src.clkr,
+	[GCC_GPU_SMMU_VOTE_CLK] = &gcc_gpu_smmu_vote_clk.clkr,
+	[GCC_MMU_TCU_VOTE_CLK] = &gcc_mmu_tcu_vote_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_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_DIV2_CLK] = &gcc_pcie_0_pipe_div2_clk.clkr,
+	[GCC_PCIE_0_PIPE_DIV2_CLK_SRC] = &gcc_pcie_0_pipe_div2_clk_src.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_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_DIV2_CLK] = &gcc_pcie_1_pipe_div2_clk.clkr,
+	[GCC_PCIE_1_PIPE_DIV2_CLK_SRC] = &gcc_pcie_1_pipe_div2_clk_src.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_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_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_ahb_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_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr,
+	[GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr,
+	[GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.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_QSPI_REF_CLK] = &gcc_qupv3_wrap1_qspi_ref_clk.clkr,
+	[GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC] = &gcc_qupv3_wrap1_qspi_ref_clk_src.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_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr,
+	[GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr,
+	[GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr,
+	[GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr,
+	[GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr,
+	[GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr,
+	[GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr,
+	[GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S5_CLK] = &gcc_qupv3_wrap2_s5_clk.clkr,
+	[GCC_QUPV3_WRAP2_S5_CLK_SRC] = &gcc_qupv3_wrap2_s5_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S6_CLK] = &gcc_qupv3_wrap2_s6_clk.clkr,
+	[GCC_QUPV3_WRAP2_S6_CLK_SRC] = &gcc_qupv3_wrap2_s6_clk_src.clkr,
+	[GCC_QUPV3_WRAP2_S7_CLK] = &gcc_qupv3_wrap2_s7_clk.clkr,
+	[GCC_QUPV3_WRAP2_S7_CLK_SRC] = &gcc_qupv3_wrap2_s7_clk_src.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_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr,
+	[GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_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_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_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_USB30_PRIM_ATB_CLK] = &gcc_usb30_prim_atb_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_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr,
+	[GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr,
+};
+
+static struct gdsc *gcc_eliza_gdscs[] = {
+	[GCC_PCIE_0_GDSC] = &gcc_pcie_0_gdsc,
+	[GCC_PCIE_0_PHY_GDSC] = &gcc_pcie_0_phy_gdsc,
+	[GCC_PCIE_1_GDSC] = &gcc_pcie_1_gdsc,
+	[GCC_PCIE_1_PHY_GDSC] = &gcc_pcie_1_phy_gdsc,
+	[GCC_UFS_MEM_PHY_GDSC] = &gcc_ufs_mem_phy_gdsc,
+	[GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc,
+	[GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc,
+	[GCC_USB3_PHY_GDSC] = &gcc_usb3_phy_gdsc,
+};
+
+static const struct qcom_reset_map gcc_eliza_resets[] = {
+	[GCC_CAMERA_BCR] = { 0x26000 },
+	[GCC_DISPLAY_BCR] = { 0x27000 },
+	[GCC_GPU_BCR] = { 0x71000 },
+	[GCC_PCIE_0_BCR] = { 0x6b000 },
+	[GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 },
+	[GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 },
+	[GCC_PCIE_0_PHY_BCR] = { 0x6c01c },
+	[GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 },
+	[GCC_PCIE_1_BCR] = { 0xac000 },
+	[GCC_PCIE_1_LINK_DOWN_BCR] = { 0x8e014 },
+	[GCC_PCIE_1_NOCSR_COM_PHY_BCR] = { 0x8e020 },
+	[GCC_PCIE_1_PHY_BCR] = { 0x8e01c },
+	[GCC_PCIE_1_PHY_NOCSR_COM_PHY_BCR] = { 0x8e024 },
+	[GCC_PCIE_PHY_BCR] = { 0x6f000 },
+	[GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c },
+	[GCC_PCIE_PHY_COM_BCR] = { 0x6f010 },
+	[GCC_PCIE_RSCC_BCR] = { 0x11000 },
+	[GCC_PDM_BCR] = { 0x33000 },
+	[GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 },
+	[GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 },
+	[GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 },
+	[GCC_QUSB2PHY_SEC_BCR] = { 0x12004 },
+	[GCC_SDCC1_BCR] = { 0xa9000 },
+	[GCC_SDCC2_BCR] = { 0x14000 },
+	[GCC_UFS_PHY_BCR] = { 0x77000 },
+	[GCC_USB30_PRIM_BCR] = { 0x39000 },
+	[GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 },
+	[GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 },
+	[GCC_USB3_PHY_PRIM_BCR] = { 0x50000 },
+	[GCC_USB3_PHY_SEC_BCR] = { 0x5000c },
+	[GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 },
+	[GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 },
+	[GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 },
+	[GCC_VIDEO_AXI1_CLK_ARES] = { 0x32028, 2 },
+	[GCC_VIDEO_BCR] = { 0x32000 },
+};
+
+static const u32 gcc_eliza_critical_cbcrs[] = {
+	0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */
+	0x26004, /* GCC_CAMERA_AHB_CLK */
+	0x26034, /* GCC_CAMERA_XO_CLK */
+	0x27004, /* GCC_DISP_AHB_CLK */
+	0x71004, /* GCC_GPU_CFG_AHB_CLK */
+	0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */
+	0x52010, /* GCC_PCIE_RSCC_XO_CLK */
+	0x32004, /* GCC_VIDEO_AHB_CLK */
+	0x32038, /* GCC_VIDEO_XO_CLK */
+};
+
+static const struct clk_rcg_dfs_data gcc_eliza_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_ref_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_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_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),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s6_clk_src),
+	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s7_clk_src),
+};
+
+static const struct regmap_config gcc_eliza_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1f41f0,
+	.fast_io = true,
+};
+
+static void clk_eliza_regs_configure(struct device *dev, struct regmap *regmap)
+{
+	/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks  */
+	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
+	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);
+}
+
+static const struct qcom_cc_driver_data gcc_eliza_driver_data = {
+	.clk_cbcrs = gcc_eliza_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(gcc_eliza_critical_cbcrs),
+	.dfs_rcgs = gcc_eliza_dfs_clocks,
+	.num_dfs_rcgs = ARRAY_SIZE(gcc_eliza_dfs_clocks),
+	.clk_regs_configure = clk_eliza_regs_configure,
+};
+
+static const struct qcom_cc_desc gcc_eliza_desc = {
+	.config = &gcc_eliza_regmap_config,
+	.clks = gcc_eliza_clocks,
+	.num_clks = ARRAY_SIZE(gcc_eliza_clocks),
+	.resets = gcc_eliza_resets,
+	.num_resets = ARRAY_SIZE(gcc_eliza_resets),
+	.gdscs = gcc_eliza_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_eliza_gdscs),
+	.driver_data = &gcc_eliza_driver_data,
+};
+
+static const struct of_device_id gcc_eliza_match_table[] = {
+	{ .compatible = "qcom,eliza-gcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gcc_eliza_match_table);
+
+static int gcc_eliza_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &gcc_eliza_desc);
+}
+
+static struct platform_driver gcc_eliza_driver = {
+	.probe = gcc_eliza_probe,
+	.driver = {
+		.name = "gcc-eliza",
+		.of_match_table = gcc_eliza_match_table,
+	},
+};
+
+static int __init gcc_eliza_init(void)
+{
+	return platform_driver_register(&gcc_eliza_driver);
+}
+subsys_initcall(gcc_eliza_init);
+
+static void __exit gcc_eliza_exit(void)
+{
+	platform_driver_unregister(&gcc_eliza_driver);
+}
+module_exit(gcc_eliza_exit);
+
+MODULE_DESCRIPTION("QTI GCC Eliza Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c
index 238e205..2736465 100644
--- a/drivers/clk/qcom/gcc-glymur.c
+++ b/drivers/clk/qcom/gcc-glymur.c
@@ -6,7 +6,6 @@
 #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>
 
@@ -8507,6 +8506,7 @@ static const struct qcom_reset_map gcc_glymur_resets[] = {
 	[GCC_VIDEO_AXI0_CLK_ARES] = { 0x3201c, 2 },
 	[GCC_VIDEO_AXI1_CLK_ARES] = { 0x32044, 2 },
 	[GCC_VIDEO_BCR] = { 0x32000 },
+	[GCC_VIDEO_AXI0C_CLK_ARES] = { 0x32030, 2 },
 };
 
 static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
@@ -8538,7 +8538,7 @@ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
 	DEFINE_RCG_DFS(gcc_qupv3_wrap2_s7_clk_src),
 };
 
-static u32 gcc_glymur_critical_cbcrs[] = {
+static const u32 gcc_glymur_critical_cbcrs[] = {
 	0x26004, /* GCC_CAMERA_AHB_CLK */
 	0x26040, /* GCC_CAMERA_XO_CLK */
 	0x27004, /* GCC_DISP_AHB_CLK */
@@ -8561,7 +8561,7 @@ static void clk_glymur_regs_configure(struct device *dev, struct regmap *regmap)
 	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
 }
 
-static struct qcom_cc_driver_data gcc_glymur_driver_data = {
+static const struct qcom_cc_driver_data gcc_glymur_driver_data = {
 	.clk_cbcrs = gcc_glymur_critical_cbcrs,
 	.num_clk_cbcrs = ARRAY_SIZE(gcc_glymur_critical_cbcrs),
 	.dfs_rcgs = gcc_dfs_clocks,
@@ -8611,5 +8611,5 @@ static void __exit gcc_glymur_exit(void)
 }
 module_exit(gcc_glymur_exit);
 
-MODULE_DESCRIPTION("QTI GCC GLYMUR Driver");
+MODULE_DESCRIPTION("QTI GCC Glymur Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gcc-ipq5210.c b/drivers/clk/qcom/gcc-ipq5210.c
new file mode 100644
index 0000000..3a786a2
--- /dev/null
+++ b/drivers/clk/qcom/gcc-ipq5210.c
@@ -0,0 +1,2661 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,ipq5210-gcc.h>
+#include <dt-bindings/reset/qcom,ipq5210-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 "clk-regmap-phy-mux.h"
+#include "reset.h"
+
+enum {
+	DT_XO,
+	DT_SLEEP_CLK,
+	DT_PCIE30_PHY0_PIPE_CLK,
+	DT_PCIE30_PHY1_PIPE_CLK,
+	DT_USB3_PHY0_CC_PIPE_CLK,
+	DT_NSS_CMN_CLK,
+};
+
+enum {
+	P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC,
+	P_GPLL0_OUT_AUX,
+	P_GPLL0_OUT_MAIN,
+	P_GPLL2_OUT_AUX,
+	P_GPLL2_OUT_MAIN,
+	P_GPLL4_OUT_AUX,
+	P_GPLL4_OUT_MAIN,
+	P_NSS_CMN_CLK,
+	P_SLEEP_CLK,
+	P_USB3PHY_0_PIPE,
+	P_XO,
+};
+
+static const struct clk_parent_data gcc_parent_data_xo = { .index = DT_XO };
+
+static struct clk_alpha_pll gpll0_main = {
+	.offset = 0x20000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+	.clkr = {
+		.enable_reg = 0xb000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll0_main",
+			.parent_data = &gcc_parent_data_xo,
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static struct clk_fixed_factor gpll0_div2 = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "gpll0_div2",
+		.parent_hws = (const struct clk_hw *[]) {
+			&gpll0_main.clkr.hw
+		},
+		.num_parents = 1,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+	.offset = 0x20000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpll0",
+		.parent_hws = (const struct clk_hw *[]) {
+			&gpll0_main.clkr.hw
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_ro_ops,
+	},
+};
+
+static struct clk_alpha_pll gpll2_main = {
+	.offset = 0x21000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+	.clkr = {
+		.enable_reg = 0xb000,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll2_main",
+			.parent_data = &gcc_parent_data_xo,
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gpll2[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gpll2 = {
+	.offset = 0x21000,
+	.post_div_table = post_div_table_gpll2,
+	.num_post_div = ARRAY_SIZE(post_div_table_gpll2),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpll2",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpll2_main.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_ro_ops,
+	},
+};
+
+static struct clk_alpha_pll gpll4_main = {
+	.offset = 0x22000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT_EVO],
+	.clkr = {
+		.enable_reg = 0xb000,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpll4_main",
+			.parent_data = &gcc_parent_data_xo,
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_ops,
+			/*
+			 * There are no consumers for this GPLL in kernel yet,
+			 * (will be added soon), so the clock framework
+			 * disables this source. But some of the clocks
+			 * initialized by boot loaders uses this source. So we
+			 * need to keep this clock ON. Add the
+			 * CLK_IGNORE_UNUSED flag so the clock will not be
+			 * disabled. Once the consumer in kernel is added, we
+			 * can get rid of this flag.
+			 */
+			.flags = CLK_IS_CRITICAL,
+		},
+	},
+};
+static const struct parent_map gcc_parent_map_xo[] = {
+	{ P_XO, 0 },
+};
+
+static const struct parent_map gcc_parent_map_0[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_0[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_1[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL4_OUT_MAIN, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_2[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll4_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_3[] = {
+	{ P_XO, 0 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+	{ .index = DT_XO },
+};
+
+static const struct parent_map gcc_parent_map_4[] = {
+	{ P_XO, 0 },
+	{ P_NSS_CMN_CLK, 1 },
+	{ P_GPLL0_OUT_AUX, 2 },
+	{ P_GPLL2_OUT_AUX, 3 },
+};
+
+static const struct clk_parent_data gcc_parent_data_4[] = {
+	{ .index = DT_XO },
+	{ .index = DT_NSS_CMN_CLK },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll2_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_5[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_AUX, 2 },
+	{ P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_5[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_6[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL2_OUT_MAIN, 2 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_6[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll2.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_7[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL4_OUT_MAIN, 2 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_7[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll4_main.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_8[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_AUX, 2 },
+	{ P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_8[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_9[] = {
+	{ P_XO, 0 },
+	{ P_GPLL4_OUT_AUX, 1 },
+	{ P_GPLL0_OUT_MAIN, 3 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_9[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll4_main.clkr.hw },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_10[] = {
+	{ P_XO, 0 },
+	{ P_GPLL4_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_AUX, 2 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_10[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll4_main.clkr.hw },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_11[] = {
+	{ P_XO, 0 },
+	{ P_GPLL4_OUT_MAIN, 1 },
+	{ P_GPLL0_OUT_AUX, 2 },
+	{ P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 4 },
+};
+
+static const struct clk_parent_data gcc_parent_data_11[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll4_main.clkr.hw },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll0_div2.hw },
+};
+
+static const struct parent_map gcc_parent_map_12[] = {
+	{ P_XO, 0 },
+	{ P_GPLL0_OUT_MAIN, 1 },
+	{ P_GPLL2_OUT_AUX, 2 },
+};
+
+static const struct clk_parent_data gcc_parent_data_12[] = {
+	{ .index = DT_XO },
+	{ .hw = &gpll0.clkr.hw },
+	{ .hw = &gpll2_main.clkr.hw },
+};
+
+static const struct parent_map gcc_parent_map_13[] = {
+	{ P_SLEEP_CLK, 6 },
+};
+
+static const struct clk_parent_data gcc_parent_data_13[] = {
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_gcc_adss_pwm_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_adss_pwm_clk_src = {
+	.cmd_rcgr = 0x1c004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_adss_pwm_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_adss_pwm_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_nss_ts_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_nss_ts_clk_src = {
+	.cmd_rcgr = 0x17088,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_nss_ts_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_nss_ts_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_system_noc_bfdcd_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(266666667, P_GPLL4_OUT_MAIN, 4.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_system_noc_bfdcd_clk_src = {
+	.cmd_rcgr = 0x2e004,
+	.freq_tbl = ftbl_gcc_system_noc_bfdcd_clk_src,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_7,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_system_noc_bfdcd_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_nssnoc_memnoc_bfdcd_clk_src[] = {
+	F(429000000, P_NSS_CMN_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_nssnoc_memnoc_bfdcd_clk_src = {
+	.cmd_rcgr = 0x17004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_4,
+	.freq_tbl = ftbl_gcc_nssnoc_memnoc_bfdcd_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_nssnoc_memnoc_bfdcd_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_pcie0_axi_m_clk_src[] = {
+	F(200000000, P_GPLL4_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie0_axi_m_clk_src = {
+	.cmd_rcgr = 0x28018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_pcie0_axi_m_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie0_axi_m_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_pcie0_axi_s_clk_src = {
+	.cmd_rcgr = 0x28020,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_pcie0_axi_m_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie0_axi_s_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_pcie0_rchng_clk_src = {
+	.cmd_rcgr = 0x28028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_adss_pwm_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie0_rchng_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie1_axi_m_clk_src[] = {
+	F(266666667, P_GPLL4_OUT_MAIN, 4.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie1_axi_m_clk_src = {
+	.cmd_rcgr = 0x29018,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_pcie1_axi_m_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie1_axi_m_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_pcie1_axi_s_clk_src = {
+	.cmd_rcgr = 0x29020,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_pcie0_axi_m_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie1_axi_s_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_pcie1_rchng_clk_src = {
+	.cmd_rcgr = 0x29028,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_adss_pwm_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie1_rchng_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_aux_clk_src[] = {
+	F(20000000, P_GPLL0_OUT_MAIN, 10, 1, 4),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_aux_clk_src = {
+	.cmd_rcgr = 0x28004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_5,
+	.freq_tbl = ftbl_gcc_pcie_aux_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_aux_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_qupv3_wrap_se0_clk_src[] = {
+	F(960000, P_XO, 10, 2, 5),
+	F(3686636, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 2, 217),
+	F(4800000, P_XO, 5, 0, 0),
+	F(7373272, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 4, 217),
+	F(9600000, P_XO, 2.5, 0, 0),
+	F(14746544, P_GCC_GPLL0_OUT_MAIN_DIV_CLK_SRC, 1, 8, 217),
+	F(16000000, P_GPLL0_OUT_MAIN, 10, 1, 5),
+	F(24000000, P_XO, 1, 0, 0),
+	F(25000000, P_GPLL0_OUT_MAIN, 16, 1, 2),
+	F(32000000, P_GPLL0_OUT_MAIN, 1, 1, 25),
+	F(40000000, P_GPLL0_OUT_MAIN, 1, 1, 20),
+	F(46400000, P_GPLL0_OUT_MAIN, 2, 29, 250),
+	F(48000000, P_GPLL0_OUT_MAIN, 1, 3, 50),
+	F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+	F(51200000, P_GPLL0_OUT_MAIN, 1, 8, 125),
+	F(56000000, P_GPLL0_OUT_MAIN, 1, 7, 100),
+	F(58986175, P_GPLL0_OUT_MAIN, 1, 16, 217),
+	F(60000000, P_GPLL0_OUT_MAIN, 1, 3, 40),
+	F(64000000, P_GPLL0_OUT_MAIN, 12.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap_se0_clk_src = {
+	.cmd_rcgr = 0x4004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se0_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_qupv3_wrap_se1_clk_src = {
+	.cmd_rcgr = 0x5004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se1_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_qupv3_wrap_se2_clk_src = {
+	.cmd_rcgr = 0x2018,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se2_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_qupv3_wrap_se3_clk_src = {
+	.cmd_rcgr = 0x2034,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se3_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_qupv3_wrap_se4_clk_src = {
+	.cmd_rcgr = 0x3018,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se4_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_qupv3_wrap_se5_clk_src = {
+	.cmd_rcgr = 0x3034,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap_se0_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap_se5_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_sdcc1_apps_clk_src[] = {
+	F(144000, P_XO, 16, 12, 125),
+	F(400000, P_XO, 12, 1, 5),
+	F(24000000, P_GPLL2_OUT_MAIN, 12, 1, 2),
+	F(48000000, P_GPLL2_OUT_MAIN, 12, 0, 0),
+	F(96000000, P_GPLL2_OUT_MAIN, 6, 0, 0),
+	F(177777778, P_GPLL0_OUT_MAIN, 4.5, 0, 0),
+	F(192000000, P_GPLL2_OUT_MAIN, 3, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
+	.cmd_rcgr = 0x33004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_6,
+	.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_6,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_6),
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sdcc1_ice_core_clk_src[] = {
+	F(300000000, P_GPLL4_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
+	.cmd_rcgr = 0x33018,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_7,
+	.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_7,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_7),
+		.ops = &clk_rcg2_floor_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_uniphy_sys_clk_src = {
+	.cmd_rcgr = 0x17090,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_nss_ts_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_uniphy_sys_clk_src",
+		.parent_data = gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_3),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_usb0_aux_clk_src = {
+	.cmd_rcgr = 0x2c018,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_8,
+	.freq_tbl = ftbl_gcc_nss_ts_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb0_aux_clk_src",
+		.parent_data = gcc_parent_data_8,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_8),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_usb0_master_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb0_master_clk_src = {
+	.cmd_rcgr = 0x2c004,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_usb0_master_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb0_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_usb0_mock_utmi_clk_src[] = {
+	F(60000000, P_GPLL4_OUT_AUX, 10, 1, 2),
+	{ }
+};
+
+static struct clk_rcg2 gcc_usb0_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x2c02c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_9,
+	.freq_tbl = ftbl_gcc_usb0_mock_utmi_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb0_mock_utmi_clk_src",
+		.parent_data = gcc_parent_data_9,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_9),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qdss_at_clk_src[] = {
+	F(240000000, P_GPLL4_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qdss_at_clk_src = {
+	.cmd_rcgr = 0x2d004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_10,
+	.freq_tbl = ftbl_gcc_qdss_at_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qdss_at_clk_src",
+		.parent_data = gcc_parent_data_10,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_10),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qdss_tsctr_clk_src[] = {
+	F(600000000, P_GPLL4_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qdss_tsctr_clk_src = {
+	.cmd_rcgr = 0x2d01c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_10,
+	.freq_tbl = ftbl_gcc_qdss_tsctr_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qdss_tsctr_clk_src",
+		.parent_data = gcc_parent_data_10,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_10),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcnoc_bfdcd_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	F(50000000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcnoc_bfdcd_clk_src = {
+	.cmd_rcgr = 0x31004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcnoc_bfdcd_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcnoc_bfdcd_clk_src",
+		.parent_data = gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_0),
+		.ops = &clk_rcg2_ops,
+		/*
+		 * There are no consumers for this source in kernel yet,
+		 * (will be added soon), so the clock framework
+		 * disables this source. But some of the clocks
+		 * initialized by boot loaders uses this source. So we
+		 * need to keep this clock ON. Add the
+		 * CLK_IGNORE_UNUSED flag so the clock will not be
+		 * disabled. Once the consumer in kernel is added, we
+		 * can get rid of this flag.
+		 */
+		.flags = CLK_IS_CRITICAL,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qpic_io_macro_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(320000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	F(400000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qpic_io_macro_clk_src = {
+	.cmd_rcgr = 0x32004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_12,
+	.freq_tbl = ftbl_gcc_qpic_io_macro_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qpic_io_macro_clk_src",
+		.parent_data = gcc_parent_data_12,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_12),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_qpic_clk_src[] = {
+	F(24000000, P_XO, 1, 0, 0),
+	F(100000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(200000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_qpic_clk_src = {
+	.cmd_rcgr = 0x32020,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_12,
+	.freq_tbl = ftbl_gcc_qpic_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qpic_clk_src",
+		.parent_data = gcc_parent_data_12,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_12),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pon_tm2x_clk_src[] = {
+	F(342860000, P_GPLL4_OUT_MAIN, 3.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pon_tm2x_clk_src = {
+	.cmd_rcgr = 0x3c004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_11,
+	.freq_tbl = ftbl_gcc_pon_tm2x_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pon_tm2x_clk_src",
+		.parent_data = gcc_parent_data_11,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_11),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_sleep_clk_src[] = {
+	F(32000, P_SLEEP_CLK, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_sleep_clk_src = {
+	.cmd_rcgr = 0x3400c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_13,
+	.freq_tbl = ftbl_gcc_sleep_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_sleep_clk_src",
+		.parent_data = gcc_parent_data_13,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_13),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_lpass_sway_clk_src[] = {
+	F(133333333, P_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_lpass_sway_clk_src = {
+	.cmd_rcgr = 0x27004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_lpass_sway_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_lpass_sway_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_lpass_axim_clk_src = {
+	.cmd_rcgr = 0x2700c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_lpass_sway_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_lpass_axim_clk_src",
+		.parent_data = gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(gcc_parent_data_1),
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_nssnoc_memnoc_div_clk_src = {
+	.reg = 0x1700c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_nssnoc_memnoc_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_nssnoc_memnoc_bfdcd_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_regmap_div gcc_usb0_mock_utmi_div_clk_src = {
+	.reg = 0x2c040,
+	.shift = 0,
+	.width = 2,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_usb0_mock_utmi_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_usb0_mock_utmi_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_fixed_factor gcc_pon_tm_div_clk_src = {
+	.mult = 1,
+	.div = 2,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pon_tm_div_clk_src",
+		.parent_hws = (const struct clk_hw *[]) {
+			&gcc_pon_tm2x_clk_src.clkr.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_branch gcc_adss_pwm_clk = {
+	.halt_reg = 0x1c00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1c00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_adss_pwm_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_adss_pwm_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cnoc_pcie0_1lane_s_clk = {
+	.halt_reg = 0x31088,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x31088,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cnoc_pcie0_1lane_s_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie0_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cnoc_pcie1_2lane_s_clk = {
+	.halt_reg = 0x3108c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3108c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cnoc_pcie1_2lane_s_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie1_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cnoc_usb_clk = {
+	.halt_reg = 0x310a8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x310a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cnoc_usb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb0_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_mdio_ahb_clk = {
+	.halt_reg = 0x17040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_mdio_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_mdio_gephy_ahb_clk = {
+	.halt_reg = 0x17098,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17098,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_mdio_gephy_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nss_ts_clk = {
+	.halt_reg = 0x17018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nss_ts_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_nss_ts_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nsscc_clk = {
+	.halt_reg = 0x17034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nsscc_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nsscfg_clk = {
+	.halt_reg = 0x1702c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1702c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nsscfg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_atb_clk = {
+	.halt_reg = 0x17014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_atb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qdss_at_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_memnoc_1_clk = {
+	.halt_reg = 0x17084,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17084,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_memnoc_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_nssnoc_memnoc_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_memnoc_clk = {
+	.halt_reg = 0x17024,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17024,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_memnoc_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_nssnoc_memnoc_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_nsscc_clk = {
+	.halt_reg = 0x17030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_nsscc_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_rcg2 gcc_xo_clk_src = {
+	.cmd_rcgr = 0x34004,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_xo,
+	.freq_tbl = ftbl_gcc_nss_ts_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_xo_clk_src",
+		.parent_data = &gcc_parent_data_xo,
+		.num_parents = 1,
+		.ops = &clk_rcg2_ops,
+	},
+};
+
+static struct clk_fixed_factor gcc_xo_div4_clk_src = {
+	.mult = 1,
+	.div = 4,
+	.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_xo_div4_clk_src",
+		.parent_hws = (const struct clk_hw *[]) {
+			&gcc_xo_clk_src.clkr.hw
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_fixed_factor_ops,
+	},
+};
+
+static struct clk_branch gcc_gephy_sys_clk = {
+	.halt_reg = 0x2a004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_gephy_sys_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_pcnoc_1_clk = {
+	.halt_reg = 0x17080,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17080,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_pcnoc_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_qosgen_ref_clk = {
+	.halt_reg = 0x1701c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1701c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_qosgen_ref_clk",
+			.parent_hws = (const struct clk_hw *[]){
+				&gcc_xo_div4_clk_src.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_snoc_1_clk = {
+	.halt_reg = 0x1707c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1707c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_snoc_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_system_noc_bfdcd_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_snoc_clk = {
+	.halt_reg = 0x17028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_snoc_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_system_noc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_timeout_ref_clk = {
+	.halt_reg = 0x17020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_timeout_ref_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_xo_div4_clk_src.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_nssnoc_xo_dcd_clk = {
+	.halt_reg = 0x17074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_nssnoc_xo_dcd_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_xo_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_ahb_clk = {
+	.halt_reg = 0x28030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_aux_clk = {
+	.halt_reg = 0x28070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_axi_m_clk = {
+	.halt_reg = 0x28038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_axi_m_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie0_axi_m_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
+	.halt_reg = 0x28048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_axi_s_bridge_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie0_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_axi_s_clk = {
+	.halt_reg = 0x28040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_axi_s_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie0_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie0_pipe_clk_src = {
+	.reg = 0x28064,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "pcie0_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_PCIE30_PHY0_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_pipe_clk = {
+	.halt_reg = 0x28068,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x28068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_pipe_clk",
+			.parent_hws = (const struct clk_hw *[]) {
+				&gcc_pcie0_pipe_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_ahb_clk = {
+	.halt_reg = 0x29030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_aux_clk = {
+	.halt_reg = 0x29074,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_axi_m_clk = {
+	.halt_reg = 0x29038,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_axi_m_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie1_axi_m_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_axi_s_bridge_clk = {
+	.halt_reg = 0x29048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_axi_s_bridge_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie1_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_axi_s_clk = {
+	.halt_reg = 0x29040,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_axi_s_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie1_axi_s_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie1_pipe_clk_src = {
+	.reg = 0x29064,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "pcie1_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_PCIE30_PHY1_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_pipe_clk = {
+	.halt_reg = 0x29068,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x29068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_pipe_clk",
+			.parent_hws = (const struct clk_hw *[]) {
+				&gcc_pcie1_pipe_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qrng_ahb_clk = {
+	.halt_reg = 0x13024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qrng_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_ahb_mst_clk = {
+	.halt_reg = 0x1014,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_ahb_mst_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_ahb_slv_clk = {
+	.halt_reg = 0x102c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_ahb_slv_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se0_clk = {
+	.halt_reg = 0x4020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x4020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se1_clk = {
+	.halt_reg = 0x5020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se2_clk = {
+	.halt_reg = 0x202c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x202c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se3_clk = {
+	.halt_reg = 0x2048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se4_clk = {
+	.halt_reg = 0x302c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x302c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap_se5_clk = {
+	.halt_reg = 0x3048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap_se5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap_se5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+	.halt_reg = 0x3303c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3303c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_sdcc1_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+	.halt_reg = 0x3302c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3302c,
+		.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 = 0x33034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x33034,
+		.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_snoc_pcie0_axi_m_clk = {
+	.halt_reg = 0x2e04c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2e04c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_snoc_pcie0_axi_m_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie0_axi_m_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_snoc_pcie1_axi_m_clk = {
+	.halt_reg = 0x2e050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2e050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_snoc_pcie1_axi_m_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie1_axi_m_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy0_ahb_clk = {
+	.halt_reg = 0x1704c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1704c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy0_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy0_sys_clk = {
+	.halt_reg = 0x17048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy0_sys_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_uniphy_sys_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy1_ahb_clk = {
+	.halt_reg = 0x1705c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1705c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy1_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy1_sys_clk = {
+	.halt_reg = 0x17058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy1_sys_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_uniphy_sys_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy2_ahb_clk = {
+	.halt_reg = 0x1706c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1706c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy2_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_uniphy2_sys_clk = {
+	.halt_reg = 0x17068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x17068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_uniphy2_sys_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_uniphy_sys_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_aux_clk = {
+	.halt_reg = 0x2c04c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c04c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb0_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_master_clk = {
+	.halt_reg = 0x2c044,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c044,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb0_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_mock_utmi_clk = {
+	.halt_reg = 0x2c050,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c050,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_usb0_mock_utmi_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_phy_cfg_ahb_clk = {
+	.halt_reg = 0x2c05c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c05c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_phy_cfg_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_usb0_pipe_clk_src = {
+	.reg = 0x2c074,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_USB3_PHY0_CC_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_pipe_clk = {
+	.halt_reg = 0x2c054,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x2c054,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_pipe_clk",
+			.parent_hws = (const struct clk_hw *[]) {
+				&gcc_usb0_pipe_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_usb0_sleep_clk = {
+	.halt_reg = 0x2c058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_usb0_sleep_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_sleep_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie0_rchng_clk = {
+	.halt_reg = 0x28028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x28028,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie0_rchng_clk",
+			.parent_hws = (const struct clk_hw *[]) {
+				&gcc_pcie0_rchng_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie1_rchng_clk = {
+	.halt_reg = 0x29028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x29028,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie1_rchng_clk",
+			.parent_hws = (const struct clk_hw *[]) {
+				&gcc_pcie1_rchng_clk_src.clkr.hw
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qpic_ahb_clk = {
+	.halt_reg = 0x32010,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x32010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qpic_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qpic_clk = {
+	.halt_reg = 0x32028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x32028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qpic_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qpic_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qpic_io_macro_clk = {
+	.halt_reg = 0x3200c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3200c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qpic_io_macro_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qpic_io_macro_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cmn_12gpll_ahb_clk = {
+	.halt_reg = 0x3a004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3a004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cmn_12gpll_ahb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cmn_12gpll_sys_clk = {
+	.halt_reg = 0x3a008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3a008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cmn_12gpll_sys_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_uniphy_sys_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qdss_at_clk = {
+	.halt_reg = 0x2d034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2d034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qdss_at_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qdss_at_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qdss_dap_clk = {
+	.halt_reg = 0x2d058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0xb004,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qdss_dap_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qdss_tsctr_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pon_apb_clk = {
+	.halt_reg = 0x3c01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3c01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pon_apb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcnoc_bfdcd_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pon_tm_clk = {
+	.halt_reg = 0x3c014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3c014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pon_tm_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pon_tm_div_clk_src.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pon_tm2x_clk = {
+	.halt_reg = 0x3c00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3c00c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pon_tm2x_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pon_tm2x_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_snoc_lpass_clk = {
+	.halt_reg = 0x2e028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2e028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_snoc_lpass_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_lpass_axim_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_lpass_sway_clk = {
+	.halt_reg = 0x27014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x27014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_lpass_sway_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_lpass_sway_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_cnoc_lpass_cfg_clk = {
+	.halt_reg = 0x31020,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x31020,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_cnoc_lpass_cfg_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_lpass_sway_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_lpass_core_axim_clk = {
+	.halt_reg = 0x27018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x27018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_lpass_core_axim_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_lpass_axim_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static __maybe_unused struct clk_regmap *gcc_ipq5210_clocks[] = {
+	[GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr,
+	[GCC_ADSS_PWM_CLK_SRC] = &gcc_adss_pwm_clk_src.clkr,
+	[GCC_CMN_12GPLL_AHB_CLK] = &gcc_cmn_12gpll_ahb_clk.clkr,
+	[GCC_CMN_12GPLL_SYS_CLK] = &gcc_cmn_12gpll_sys_clk.clkr,
+	[GCC_CNOC_LPASS_CFG_CLK] = &gcc_cnoc_lpass_cfg_clk.clkr,
+	[GCC_CNOC_PCIE0_1LANE_S_CLK] = &gcc_cnoc_pcie0_1lane_s_clk.clkr,
+	[GCC_CNOC_PCIE1_2LANE_S_CLK] = &gcc_cnoc_pcie1_2lane_s_clk.clkr,
+	[GCC_CNOC_USB_CLK] = &gcc_cnoc_usb_clk.clkr,
+	[GCC_GEPHY_SYS_CLK] = &gcc_gephy_sys_clk.clkr,
+	[GCC_LPASS_AXIM_CLK_SRC] = &gcc_lpass_axim_clk_src.clkr,
+	[GCC_LPASS_CORE_AXIM_CLK] = &gcc_lpass_core_axim_clk.clkr,
+	[GCC_LPASS_SWAY_CLK] = &gcc_lpass_sway_clk.clkr,
+	[GCC_LPASS_SWAY_CLK_SRC] = &gcc_lpass_sway_clk_src.clkr,
+	[GCC_MDIO_AHB_CLK] = &gcc_mdio_ahb_clk.clkr,
+	[GCC_MDIO_GEPHY_AHB_CLK] = &gcc_mdio_gephy_ahb_clk.clkr,
+	[GCC_NSS_TS_CLK] = &gcc_nss_ts_clk.clkr,
+	[GCC_NSS_TS_CLK_SRC] = &gcc_nss_ts_clk_src.clkr,
+	[GCC_NSSCC_CLK] = &gcc_nsscc_clk.clkr,
+	[GCC_NSSCFG_CLK] = &gcc_nsscfg_clk.clkr,
+	[GCC_NSSNOC_ATB_CLK] = &gcc_nssnoc_atb_clk.clkr,
+	[GCC_NSSNOC_MEMNOC_1_CLK] = &gcc_nssnoc_memnoc_1_clk.clkr,
+	[GCC_NSSNOC_MEMNOC_BFDCD_CLK_SRC] = &gcc_nssnoc_memnoc_bfdcd_clk_src.clkr,
+	[GCC_NSSNOC_MEMNOC_CLK] = &gcc_nssnoc_memnoc_clk.clkr,
+	[GCC_NSSNOC_MEMNOC_DIV_CLK_SRC] = &gcc_nssnoc_memnoc_div_clk_src.clkr,
+	[GCC_NSSNOC_NSSCC_CLK] = &gcc_nssnoc_nsscc_clk.clkr,
+	[GCC_NSSNOC_PCNOC_1_CLK] = &gcc_nssnoc_pcnoc_1_clk.clkr,
+	[GCC_NSSNOC_QOSGEN_REF_CLK] = &gcc_nssnoc_qosgen_ref_clk.clkr,
+	[GCC_NSSNOC_SNOC_1_CLK] = &gcc_nssnoc_snoc_1_clk.clkr,
+	[GCC_NSSNOC_SNOC_CLK] = &gcc_nssnoc_snoc_clk.clkr,
+	[GCC_NSSNOC_TIMEOUT_REF_CLK] = &gcc_nssnoc_timeout_ref_clk.clkr,
+	[GCC_NSSNOC_XO_DCD_CLK] = &gcc_nssnoc_xo_dcd_clk.clkr,
+	[GCC_PCIE0_AHB_CLK] = &gcc_pcie0_ahb_clk.clkr,
+	[GCC_PCIE0_AUX_CLK] = &gcc_pcie0_aux_clk.clkr,
+	[GCC_PCIE0_AXI_M_CLK] = &gcc_pcie0_axi_m_clk.clkr,
+	[GCC_PCIE0_AXI_M_CLK_SRC] = &gcc_pcie0_axi_m_clk_src.clkr,
+	[GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,
+	[GCC_PCIE0_AXI_S_CLK] = &gcc_pcie0_axi_s_clk.clkr,
+	[GCC_PCIE0_AXI_S_CLK_SRC] = &gcc_pcie0_axi_s_clk_src.clkr,
+	[GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr,
+	[GCC_PCIE0_PIPE_CLK_SRC] = &gcc_pcie0_pipe_clk_src.clkr,
+	[GCC_PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr,
+	[GCC_PCIE0_RCHNG_CLK_SRC] = &gcc_pcie0_rchng_clk_src.clkr,
+	[GCC_PCIE1_AHB_CLK] = &gcc_pcie1_ahb_clk.clkr,
+	[GCC_PCIE1_AUX_CLK] = &gcc_pcie1_aux_clk.clkr,
+	[GCC_PCIE1_AXI_M_CLK] = &gcc_pcie1_axi_m_clk.clkr,
+	[GCC_PCIE1_AXI_M_CLK_SRC] = &gcc_pcie1_axi_m_clk_src.clkr,
+	[GCC_PCIE1_AXI_S_BRIDGE_CLK] = &gcc_pcie1_axi_s_bridge_clk.clkr,
+	[GCC_PCIE1_AXI_S_CLK] = &gcc_pcie1_axi_s_clk.clkr,
+	[GCC_PCIE1_AXI_S_CLK_SRC] = &gcc_pcie1_axi_s_clk_src.clkr,
+	[GCC_PCIE1_PIPE_CLK] = &gcc_pcie1_pipe_clk.clkr,
+	[GCC_PCIE1_PIPE_CLK_SRC] = &gcc_pcie1_pipe_clk_src.clkr,
+	[GCC_PCIE1_RCHNG_CLK] = &gcc_pcie1_rchng_clk.clkr,
+	[GCC_PCIE1_RCHNG_CLK_SRC] = &gcc_pcie1_rchng_clk_src.clkr,
+	[GCC_PCIE_AUX_CLK_SRC] = &gcc_pcie_aux_clk_src.clkr,
+	[GCC_PCNOC_BFDCD_CLK_SRC] = &gcc_pcnoc_bfdcd_clk_src.clkr,
+	[GCC_PON_APB_CLK] = &gcc_pon_apb_clk.clkr,
+	[GCC_PON_TM_CLK] = &gcc_pon_tm_clk.clkr,
+	[GCC_PON_TM2X_CLK] = &gcc_pon_tm2x_clk.clkr,
+	[GCC_PON_TM2X_CLK_SRC] = &gcc_pon_tm2x_clk_src.clkr,
+	[GCC_QDSS_AT_CLK] = &gcc_qdss_at_clk.clkr,
+	[GCC_QDSS_AT_CLK_SRC] = &gcc_qdss_at_clk_src.clkr,
+	[GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_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_CLK_SRC] = &gcc_qpic_clk_src.clkr,
+	[GCC_QPIC_IO_MACRO_CLK] = &gcc_qpic_io_macro_clk.clkr,
+	[GCC_QPIC_IO_MACRO_CLK_SRC] = &gcc_qpic_io_macro_clk_src.clkr,
+	[GCC_QRNG_AHB_CLK] = &gcc_qrng_ahb_clk.clkr,
+	[GCC_QUPV3_AHB_MST_CLK] = &gcc_qupv3_ahb_mst_clk.clkr,
+	[GCC_QUPV3_AHB_SLV_CLK] = &gcc_qupv3_ahb_slv_clk.clkr,
+	[GCC_QUPV3_WRAP_SE0_CLK] = &gcc_qupv3_wrap_se0_clk.clkr,
+	[GCC_QUPV3_WRAP_SE0_CLK_SRC] = &gcc_qupv3_wrap_se0_clk_src.clkr,
+	[GCC_QUPV3_WRAP_SE1_CLK] = &gcc_qupv3_wrap_se1_clk.clkr,
+	[GCC_QUPV3_WRAP_SE1_CLK_SRC] = &gcc_qupv3_wrap_se1_clk_src.clkr,
+	[GCC_QUPV3_WRAP_SE2_CLK] = &gcc_qupv3_wrap_se2_clk.clkr,
+	[GCC_QUPV3_WRAP_SE2_CLK_SRC] = &gcc_qupv3_wrap_se2_clk_src.clkr,
+	[GCC_QUPV3_WRAP_SE3_CLK] = &gcc_qupv3_wrap_se3_clk.clkr,
+	[GCC_QUPV3_WRAP_SE3_CLK_SRC] = &gcc_qupv3_wrap_se3_clk_src.clkr,
+	[GCC_QUPV3_WRAP_SE4_CLK] = &gcc_qupv3_wrap_se4_clk.clkr,
+	[GCC_QUPV3_WRAP_SE4_CLK_SRC] = &gcc_qupv3_wrap_se4_clk_src.clkr,
+	[GCC_QUPV3_WRAP_SE5_CLK] = &gcc_qupv3_wrap_se5_clk.clkr,
+	[GCC_QUPV3_WRAP_SE5_CLK_SRC] = &gcc_qupv3_wrap_se5_clk_src.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_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr,
+	[GCC_SNOC_LPASS_CLK] = &gcc_snoc_lpass_clk.clkr,
+	[GCC_SNOC_PCIE0_AXI_M_CLK] = &gcc_snoc_pcie0_axi_m_clk.clkr,
+	[GCC_SNOC_PCIE1_AXI_M_CLK] = &gcc_snoc_pcie1_axi_m_clk.clkr,
+	[GCC_SYSTEM_NOC_BFDCD_CLK_SRC] = &gcc_system_noc_bfdcd_clk_src.clkr,
+	[GCC_UNIPHY0_AHB_CLK] = &gcc_uniphy0_ahb_clk.clkr,
+	[GCC_UNIPHY0_SYS_CLK] = &gcc_uniphy0_sys_clk.clkr,
+	[GCC_UNIPHY1_AHB_CLK] = &gcc_uniphy1_ahb_clk.clkr,
+	[GCC_UNIPHY1_SYS_CLK] = &gcc_uniphy1_sys_clk.clkr,
+	[GCC_UNIPHY2_AHB_CLK] = &gcc_uniphy2_ahb_clk.clkr,
+	[GCC_UNIPHY2_SYS_CLK] = &gcc_uniphy2_sys_clk.clkr,
+	[GCC_UNIPHY_SYS_CLK_SRC] = &gcc_uniphy_sys_clk_src.clkr,
+	[GCC_USB0_AUX_CLK] = &gcc_usb0_aux_clk.clkr,
+	[GCC_USB0_AUX_CLK_SRC] = &gcc_usb0_aux_clk_src.clkr,
+	[GCC_USB0_MASTER_CLK] = &gcc_usb0_master_clk.clkr,
+	[GCC_USB0_MASTER_CLK_SRC] = &gcc_usb0_master_clk_src.clkr,
+	[GCC_USB0_MOCK_UTMI_CLK] = &gcc_usb0_mock_utmi_clk.clkr,
+	[GCC_USB0_MOCK_UTMI_CLK_SRC] = &gcc_usb0_mock_utmi_clk_src.clkr,
+	[GCC_USB0_MOCK_UTMI_DIV_CLK_SRC] = &gcc_usb0_mock_utmi_div_clk_src.clkr,
+	[GCC_USB0_PHY_CFG_AHB_CLK] = &gcc_usb0_phy_cfg_ahb_clk.clkr,
+	[GCC_USB0_PIPE_CLK] = &gcc_usb0_pipe_clk.clkr,
+	[GCC_USB0_PIPE_CLK_SRC] = &gcc_usb0_pipe_clk_src.clkr,
+	[GCC_USB0_SLEEP_CLK] = &gcc_usb0_sleep_clk.clkr,
+	[GCC_XO_CLK_SRC] = &gcc_xo_clk_src.clkr,
+	[GPLL0_MAIN] = &gpll0_main.clkr,
+	[GPLL0] = &gpll0.clkr,
+	[GPLL2_MAIN] = &gpll2_main.clkr,
+	[GPLL2] = &gpll2.clkr,
+	[GPLL4_MAIN] = &gpll4_main.clkr,
+};
+
+static const struct qcom_reset_map gcc_ipq5210_resets[] = {
+	[GCC_ADSS_BCR] = { 0x1c000 },
+	[GCC_ADSS_PWM_ARES] = { 0x1c00c, 2 },
+	[GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR] = { 0x38000 },
+	[GCC_APC0_VOLTAGE_DROOP_DETECTOR_GPLL0_ARES] = { 0x3800c, 2 },
+	[GCC_APSS_AHB_ARES] = { 0x24014, 2 },
+	[GCC_APSS_ATB_ARES] = { 0x24034, 2 },
+	[GCC_APSS_AXI_ARES] = { 0x24018, 2 },
+	[GCC_APSS_TS_ARES] = { 0x24030, 2 },
+	[GCC_BOOT_ROM_AHB_ARES] = { 0x1302c, 2 },
+	[GCC_BOOT_ROM_BCR] = { 0x13028 },
+	[GCC_GEPHY_BCR] = { 0x2a000 },
+	[GCC_GEPHY_SYS_ARES] = { 0x2a004, 2 },
+	[GCC_GP1_ARES] = { 0x8018, 2 },
+	[GCC_GP2_ARES] = { 0x9018, 2 },
+	[GCC_GP3_ARES] = { 0xa018, 2 },
+	[GCC_MDIO_AHB_ARES] = { 0x17040, 2 },
+	[GCC_MDIO_BCR] = { 0x1703c },
+	[GCC_MDIO_GEPHY_AHB_ARES] = { 0x17098, 2 },
+	[GCC_NSS_BCR] = { 0x17000 },
+	[GCC_NSS_TS_ARES] = { 0x17018, 2 },
+	[GCC_NSSCC_ARES] = { 0x17034, 2 },
+	[GCC_NSSCFG_ARES] = { 0x1702c, 2 },
+	[GCC_NSSNOC_ATB_ARES] = { 0x17014, 2 },
+	[GCC_NSSNOC_MEMNOC_1_ARES] = { 0x17084, 2 },
+	[GCC_NSSNOC_MEMNOC_ARES] = { 0x17024, 2 },
+	[GCC_NSSNOC_NSSCC_ARES] = { 0x17030, 2 },
+	[GCC_NSSNOC_PCNOC_1_ARES] = { 0x17080, 2 },
+	[GCC_NSSNOC_QOSGEN_REF_ARES] = { 0x1701c, 2 },
+	[GCC_NSSNOC_SNOC_1_ARES] = { 0x1707c, 2 },
+	[GCC_NSSNOC_SNOC_ARES] = { 0x17028, 2 },
+	[GCC_NSSNOC_TIMEOUT_REF_ARES] = { 0x17020, 2 },
+	[GCC_NSSNOC_XO_DCD_ARES] = { 0x17074, 2 },
+	[GCC_PCIE0_AHB_ARES] = { 0x28030, 2 },
+	[GCC_PCIE0_AUX_ARES] = { 0x28070, 2 },
+	[GCC_PCIE0_AXI_M_ARES] = { 0x28038, 2 },
+	[GCC_PCIE0_AXI_S_BRIDGE_ARES] = { 0x28048, 2 },
+	[GCC_PCIE0_AXI_S_ARES] = { 0x28040, 2 },
+	[GCC_PCIE0_BCR] = { 0x28000 },
+	[GCC_PCIE0_LINK_DOWN_BCR] = { 0x28054 },
+	[GCC_PCIE0_PIPE_RESET] = { 0x28058, 0 },
+	[GCC_PCIE0_CORE_STICKY_RESET] = { 0x28058, 1 },
+	[GCC_PCIE0_AXI_S_STICKY_RESET] = { 0x28058, 2 },
+	[GCC_PCIE0_AXI_S_RESET] = { 0x28058, 3 },
+	[GCC_PCIE0_AXI_M_STICKY_RESET] = { 0x28058, 4 },
+	[GCC_PCIE0_AXI_M_RESET] = { 0x28058, 5 },
+	[GCC_PCIE0_AUX_RESET] = { 0x28058, 6 },
+	[GCC_PCIE0_AHB_RESET] = { 0x28058, 7 },
+	[GCC_PCIE0_PHY_BCR] = { 0x28060 },
+	[GCC_PCIE0_PIPE_ARES] = { 0x28068, 2 },
+	[GCC_PCIE0PHY_PHY_BCR] = { 0x2805c },
+	[GCC_PCIE1_AHB_ARES] = { 0x29030, 2 },
+	[GCC_PCIE1_AUX_ARES] = { 0x29074, 2 },
+	[GCC_PCIE1_AXI_M_ARES] = { 0x29038, 2 },
+	[GCC_PCIE1_AXI_S_BRIDGE_ARES] = { 0x29048, 2 },
+	[GCC_PCIE1_AXI_S_ARES] = { 0x29040, 2 },
+	[GCC_PCIE1_BCR] = { 0x29000 },
+	[GCC_PCIE1_LINK_DOWN_BCR] = { 0x29054 },
+	[GCC_PCIE1_PIPE_RESET] = { 0x29058, 0 },
+	[GCC_PCIE1_CORE_STICKY_RESET] = { 0x29058, 1 },
+	[GCC_PCIE1_AXI_S_STICKY_RESET] = { 0x29058, 2 },
+	[GCC_PCIE1_AXI_S_RESET] = { 0x29058, 3 },
+	[GCC_PCIE1_AXI_M_STICKY_RESET] = { 0x29058, 4 },
+	[GCC_PCIE1_AXI_M_RESET] = { 0x29058, 5 },
+	[GCC_PCIE1_AUX_RESET] = { 0x29058, 6 },
+	[GCC_PCIE1_AHB_RESET] = { 0x29058, 7 },
+	[GCC_PCIE1_PHY_BCR] = { 0x29060 },
+	[GCC_PCIE1_PIPE_ARES] = { 0x29068, 2 },
+	[GCC_PCIE1PHY_PHY_BCR] = { 0x2905c },
+	[GCC_QRNG_AHB_ARES] = { 0x13024, 2 },
+	[GCC_QRNG_BCR] = { 0x13020 },
+	[GCC_QUPV3_2X_CORE_ARES] = { 0x1020, 2 },
+	[GCC_QUPV3_AHB_MST_ARES] = { 0x1014, 2 },
+	[GCC_QUPV3_AHB_SLV_ARES] = { 0x102c, 2 },
+	[GCC_QUPV3_BCR] = { 0x1000 },
+	[GCC_QUPV3_CORE_ARES] = { 0x1018, 2 },
+	[GCC_QUPV3_WRAP_SE0_ARES] = { 0x4020, 2 },
+	[GCC_QUPV3_WRAP_SE0_BCR] = { 0x4000 },
+	[GCC_QUPV3_WRAP_SE1_ARES] = { 0x5020, 2 },
+	[GCC_QUPV3_WRAP_SE1_BCR] = { 0x5000 },
+	[GCC_QUPV3_WRAP_SE2_ARES] = { 0x202c, 2 },
+	[GCC_QUPV3_WRAP_SE2_BCR] = { 0x2000 },
+	[GCC_QUPV3_WRAP_SE3_ARES] = { 0x2048, 2 },
+	[GCC_QUPV3_WRAP_SE3_BCR] = { 0x2030 },
+	[GCC_QUPV3_WRAP_SE4_ARES] = { 0x302c, 2 },
+	[GCC_QUPV3_WRAP_SE4_BCR] = { 0x3000 },
+	[GCC_QUPV3_WRAP_SE5_ARES] = { 0x3048, 2 },
+	[GCC_QUPV3_WRAP_SE5_BCR] = { 0x3030 },
+	[GCC_QUSB2_0_PHY_BCR] = { 0x2c068 },
+	[GCC_SDCC1_AHB_ARES] = { 0x3303c, 2 },
+	[GCC_SDCC1_APPS_ARES] = { 0x3302c, 2 },
+	[GCC_SDCC1_ICE_CORE_ARES] = { 0x33034, 2 },
+	[GCC_SDCC_BCR] = { 0x33000 },
+	[GCC_TLMM_AHB_ARES] = { 0x3e004, 2 },
+	[GCC_TLMM_ARES] = { 0x3e008, 2 },
+	[GCC_TLMM_BCR] = { 0x3e000 },
+	[GCC_UNIPHY0_AHB_ARES] = { 0x1704c, 2 },
+	[GCC_UNIPHY0_BCR] = { 0x17044 },
+	[GCC_UNIPHY0_SYS_ARES] = { 0x17048, 2 },
+	[GCC_UNIPHY1_AHB_ARES] = { 0x1705c, 2 },
+	[GCC_UNIPHY1_BCR] = { 0x17054 },
+	[GCC_UNIPHY1_SYS_ARES] = { 0x17058, 2 },
+	[GCC_UNIPHY2_AHB_ARES] = { 0x1706c, 2 },
+	[GCC_UNIPHY2_BCR] = { 0x17064 },
+	[GCC_UNIPHY2_SYS_ARES] = { 0x17068, 2 },
+	[GCC_USB0_AUX_ARES] = { 0x2c04c, 2 },
+	[GCC_USB0_MASTER_ARES] = { 0x2c044, 2 },
+	[GCC_USB0_MOCK_UTMI_ARES] = { 0x2c050, 2 },
+	[GCC_USB0_PHY_BCR] = { 0x2c06c },
+	[GCC_USB0_PHY_CFG_AHB_ARES] = { 0x2c05c, 2 },
+	[GCC_USB0_PIPE_ARES] = { 0x2c054, 2 },
+	[GCC_USB0_SLEEP_ARES] = { 0x2c058, 2 },
+	[GCC_USB3PHY_0_PHY_BCR] = { 0x2c070 },
+	[GCC_USB_BCR] = { 0x2c000 },
+	[GCC_QDSS_BCR] = { 0x2d000 },
+};
+
+static const struct of_device_id gcc_ipq5210_match_table[] = {
+	{ .compatible = "qcom,ipq5210-gcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gcc_ipq5210_match_table);
+
+static const struct regmap_config gcc_ipq5210_regmap_config = {
+	.reg_bits       = 32,
+	.reg_stride     = 4,
+	.val_bits       = 32,
+	.max_register   = 0x3f024,
+	.fast_io        = true,
+};
+
+static struct clk_hw *gcc_ipq5210_hws[] = {
+	&gpll0_div2.hw,
+	&gcc_xo_div4_clk_src.hw,
+	&gcc_pon_tm_div_clk_src.hw,
+};
+
+static const struct qcom_cc_desc gcc_ipq5210_desc = {
+	.config = &gcc_ipq5210_regmap_config,
+	.clks = gcc_ipq5210_clocks,
+	.num_clks = ARRAY_SIZE(gcc_ipq5210_clocks),
+	.resets = gcc_ipq5210_resets,
+	.num_resets = ARRAY_SIZE(gcc_ipq5210_resets),
+	.clk_hws = gcc_ipq5210_hws,
+	.num_clk_hws = ARRAY_SIZE(gcc_ipq5210_hws),
+};
+
+static int gcc_ipq5210_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &gcc_ipq5210_desc);
+}
+
+static struct platform_driver gcc_ipq5210_driver = {
+	.probe = gcc_ipq5210_probe,
+	.driver = {
+		.name   = "qcom,gcc-ipq5210",
+		.of_match_table = gcc_ipq5210_match_table,
+	},
+};
+
+static int __init gcc_ipq5210_init(void)
+{
+	return platform_driver_register(&gcc_ipq5210_driver);
+}
+core_initcall(gcc_ipq5210_init);
+
+static void __exit gcc_ipq5210_exit(void)
+{
+	platform_driver_unregister(&gcc_ipq5210_driver);
+}
+module_exit(gcc_ipq5210_exit);
+
+MODULE_DESCRIPTION("QTI GCC IPQ5210 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c
index d4fc491..6943dc5 100644
--- a/drivers/clk/qcom/gcc-ipq6018.c
+++ b/drivers/clk/qcom/gcc-ipq6018.c
@@ -400,7 +400,7 @@ static struct clk_branch gcc_xo_clk_src = {
 				.fw_name = "xo",
 			},
 			.num_parents = 1,
-			.flags = CLK_SET_RATE_PARENT,
+			.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
 			.ops = &clk_branch2_ops,
 		},
 	},
diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c
index b974328..6e628b5 100644
--- a/drivers/clk/qcom/gcc-kaanapali.c
+++ b/drivers/clk/qcom/gcc-kaanapali.c
@@ -6,7 +6,6 @@
 #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>
 
@@ -3458,7 +3457,7 @@ static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
 	DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src),
 };
 
-static u32 gcc_kaanapali_critical_cbcrs[] = {
+static const u32 gcc_kaanapali_critical_cbcrs[] = {
 	0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */
 	0x26004, /* GCC_CAMERA_AHB_CLK */
 	0x2603c, /* GCC_CAMERA_XO_CLK */
@@ -3486,7 +3485,7 @@ static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regm
 	qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
 }
 
-static struct qcom_cc_driver_data gcc_kaanapali_driver_data = {
+static const struct qcom_cc_driver_data gcc_kaanapali_driver_data = {
 	.clk_cbcrs = gcc_kaanapali_critical_cbcrs,
 	.num_clk_cbcrs = ARRAY_SIZE(gcc_kaanapali_critical_cbcrs),
 	.dfs_rcgs = gcc_dfs_clocks,
diff --git a/drivers/clk/qcom/gcc-milos.c b/drivers/clk/qcom/gcc-milos.c
index 81fa09e..67d0eee 100644
--- a/drivers/clk/qcom/gcc-milos.c
+++ b/drivers/clk/qcom/gcc-milos.c
@@ -3152,7 +3152,7 @@ static struct gdsc *gcc_milos_gdscs[] = {
 	[USB3_PHY_GDSC] = &usb3_phy_gdsc,
 };
 
-static u32 gcc_milos_critical_cbcrs[] = {
+static const u32 gcc_milos_critical_cbcrs[] = {
 	0x26004, /* GCC_CAMERA_AHB_CLK */
 	0x26018, /* GCC_CAMERA_HF_XO_CLK */
 	0x2601c, /* GCC_CAMERA_SF_XO_CLK */
@@ -3171,7 +3171,7 @@ static const struct regmap_config gcc_milos_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data gcc_milos_driver_data = {
+static const struct qcom_cc_driver_data gcc_milos_driver_data = {
 	.clk_cbcrs = gcc_milos_critical_cbcrs,
 	.num_clk_cbcrs = ARRAY_SIZE(gcc_milos_critical_cbcrs),
 	.dfs_rcgs = gcc_milos_dfs_clocks,
diff --git a/drivers/clk/qcom/gcc-nord.c b/drivers/clk/qcom/gcc-nord.c
new file mode 100644
index 0000000..3098d8f
--- /dev/null
+++ b/drivers/clk/qcom/gcc-nord.c
@@ -0,0 +1,1902 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,nord-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_A_PIPE_CLK,
+	DT_PCIE_B_PIPE_CLK,
+	DT_PCIE_C_PIPE_CLK,
+	DT_PCIE_D_PIPE_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_GCC_GPLL0_OUT_EVEN,
+	P_GCC_GPLL0_OUT_MAIN,
+	P_PCIE_A_PIPE_CLK,
+	P_PCIE_B_PIPE_CLK,
+	P_PCIE_C_PIPE_CLK,
+	P_PCIE_D_PIPE_CLK,
+	P_SLEEP_CLK,
+};
+
+static struct clk_alpha_pll gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x9d020,
+		.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_ole_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_OLE],
+	.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_ole_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_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data gcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map gcc_parent_map_2[] = {
+	{ 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_2[] = {
+	{ .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_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GCC_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data gcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &gcc_gpll0.clkr.hw },
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_a_pipe_clk_src = {
+	.reg = 0x49094,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_PCIE_A_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_b_pipe_clk_src = {
+	.reg = 0x4a094,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_PCIE_B_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_c_pipe_clk_src = {
+	.reg = 0x4b094,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_PCIE_C_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux gcc_pcie_d_pipe_clk_src = {
+	.reg = 0x4c094,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_pipe_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_PCIE_D_PIPE_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = {
+	F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	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 = 0x30004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.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),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x31004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_2,
+	.freq_tbl = ftbl_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.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),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gcc_pcie_a_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_a_aux_clk_src = {
+	.cmd_rcgr = 0x49098,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_a_aux_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_a_phy_aux_clk_src = {
+	.cmd_rcgr = 0x4d020,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_a_phy_aux_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 const struct freq_tbl ftbl_gcc_pcie_a_phy_rchng_clk_src[] = {
+	F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pcie_a_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x4907c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_a_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_a_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_b_aux_clk_src = {
+	.cmd_rcgr = 0x4a098,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_b_aux_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_b_phy_aux_clk_src = {
+	.cmd_rcgr = 0x4e020,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_b_phy_aux_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_b_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x4a07c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_a_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_b_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_c_aux_clk_src = {
+	.cmd_rcgr = 0x4b098,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_c_aux_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_c_phy_aux_clk_src = {
+	.cmd_rcgr = 0x4f020,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_c_phy_aux_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_c_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x4b07c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_a_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_c_phy_rchng_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_pcie_d_aux_clk_src = {
+	.cmd_rcgr = 0x4c098,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_d_aux_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_d_phy_aux_clk_src = {
+	.cmd_rcgr = 0x50020,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_1,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_d_phy_aux_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_d_phy_rchng_clk_src = {
+	.cmd_rcgr = 0x4c07c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_3,
+	.freq_tbl = ftbl_gcc_pcie_a_phy_rchng_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_d_phy_rchng_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_pcie_noc_refgen_clk_src = {
+	.cmd_rcgr = 0x52094,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_noc_refgen_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_noc_safety_clk_src = {
+	.cmd_rcgr = 0x520ac,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pcie_a_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_pcie_noc_safety_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(40000000, P_GCC_GPLL0_OUT_MAIN, 15, 0, 0),
+	F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gcc_pdm2_clk_src = {
+	.cmd_rcgr = 0x1a010,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_pdm2_clk_src,
+	.hw_clk_ctrl = true,
+	.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_wrap3_qspi_ref_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(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375),
+	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(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375),
+	F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75),
+	F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625),
+	F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0),
+	F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_init_data gcc_qupv3_wrap3_qspi_ref_clk_src_init = {
+	.name = "gcc_qupv3_wrap3_qspi_ref_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_no_init_park_ops,
+};
+
+static struct clk_rcg2 gcc_qupv3_wrap3_qspi_ref_clk_src = {
+	.cmd_rcgr = 0x23174,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = gcc_parent_map_0,
+	.freq_tbl = ftbl_gcc_qupv3_wrap3_qspi_ref_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &gcc_qupv3_wrap3_qspi_ref_clk_src_init,
+};
+
+static struct clk_regmap_div gcc_qupv3_wrap3_s0_clk_src = {
+	.reg = 0x2316c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gcc_qupv3_wrap3_s0_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gcc_qupv3_wrap3_qspi_ref_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch gcc_boot_rom_ahb_clk = {
+	.halt_reg = 0x1f004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1f004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_boot_rom_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_gp1_clk = {
+	.halt_reg = 0x30000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x30000,
+		.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 = 0x31000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x31000,
+		.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_mmu_0_tcu_vote_clk = {
+	.halt_reg = 0x7d094,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7d094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_mmu_0_tcu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_aux_clk = {
+	.halt_reg = 0x49058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x49058,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_a_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_cfg_ahb_clk = {
+	.halt_reg = 0x49054,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x49054,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_dti_qtc_clk = {
+	.halt_reg = 0x49018,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x49018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_dti_qtc_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_mstr_axi_clk = {
+	.halt_reg = 0x49040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x49040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_phy_aux_clk = {
+	.halt_reg = 0x4d01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_a_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_phy_rchng_clk = {
+	.halt_reg = 0x49078,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x49078,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_a_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_pipe_clk = {
+	.halt_reg = 0x49068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x49068,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_a_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_slv_axi_clk = {
+	.halt_reg = 0x4902c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4902c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_a_slv_q2a_axi_clk = {
+	.halt_reg = 0x49024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x49024,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_a_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_aux_clk = {
+	.halt_reg = 0x4a058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(23),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_b_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_cfg_ahb_clk = {
+	.halt_reg = 0x4a054,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4a054,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_dti_qtc_clk = {
+	.halt_reg = 0x4a018,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4a018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(17),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_dti_qtc_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_mstr_axi_clk = {
+	.halt_reg = 0x4a040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4a040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(21),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_phy_aux_clk = {
+	.halt_reg = 0x4e01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_b_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_phy_rchng_clk = {
+	.halt_reg = 0x4a078,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_b_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_pipe_clk = {
+	.halt_reg = 0x4a068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(24),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_b_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_slv_axi_clk = {
+	.halt_reg = 0x4a02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4a02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_b_slv_q2a_axi_clk = {
+	.halt_reg = 0x4a024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_b_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_aux_clk = {
+	.halt_reg = 0x4b058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_c_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_cfg_ahb_clk = {
+	.halt_reg = 0x4b054,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4b054,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(31),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_dti_qtc_clk = {
+	.halt_reg = 0x4b018,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4b018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_dti_qtc_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_mstr_axi_clk = {
+	.halt_reg = 0x4b040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4b040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(30),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_phy_aux_clk = {
+	.halt_reg = 0x4f01c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_c_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_phy_rchng_clk = {
+	.halt_reg = 0x4b078,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_c_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_pipe_clk = {
+	.halt_reg = 0x4b068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_c_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_slv_axi_clk = {
+	.halt_reg = 0x4b02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4b02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(29),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_c_slv_q2a_axi_clk = {
+	.halt_reg = 0x4b024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d008,
+		.enable_mask = BIT(28),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_c_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_aux_clk = {
+	.halt_reg = 0x4c058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_d_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_cfg_ahb_clk = {
+	.halt_reg = 0x4c054,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4c054,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_cfg_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_dti_qtc_clk = {
+	.halt_reg = 0x4c018,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4c018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_dti_qtc_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_mstr_axi_clk = {
+	.halt_reg = 0x4c040,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x4c040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_phy_aux_clk = {
+	.halt_reg = 0x5001c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_d_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_phy_rchng_clk = {
+	.halt_reg = 0x4c078,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(11),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_phy_rchng_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_d_phy_rchng_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_pipe_clk = {
+	.halt_reg = 0x4c068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(10),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_d_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_slv_axi_clk = {
+	.halt_reg = 0x4c02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x4c02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_slv_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_d_slv_q2a_axi_clk = {
+	.halt_reg = 0x4c024,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_d_slv_q2a_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_link_ahb_clk = {
+	.halt_reg = 0x52464,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x52464,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_link_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_link_xo_clk = {
+	.halt_reg = 0x52468,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x52468,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x52468,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_link_xo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_async_bridge_clk = {
+	.halt_reg = 0x52048,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x52048,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(18),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_async_bridge_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_cnoc_sf_qx_clk = {
+	.halt_reg = 0x52040,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x52040,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(24),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_cnoc_sf_qx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_m_cfg_clk = {
+	.halt_reg = 0x52060,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x52060,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_m_cfg_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_m_pdb_clk = {
+	.halt_reg = 0x52084,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x52084,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_m_pdb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_mstr_axi_clk = {
+	.halt_reg = 0x52050,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x52050,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_mstr_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_pwrctl_clk = {
+	.halt_reg = 0x52080,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_pwrctl_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_qosgen_extref_clk = {
+	.halt_reg = 0x52074,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_qosgen_extref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_refgen_clk = {
+	.halt_reg = 0x52078,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x52078,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_refgen_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_noc_refgen_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_s_cfg_clk = {
+	.halt_reg = 0x52064,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_s_cfg_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_s_pdb_clk = {
+	.halt_reg = 0x5208c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x5208c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(9),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_s_pdb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_safety_clk = {
+	.halt_reg = 0x5207c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x5207c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_safety_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_pcie_noc_safety_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_slave_axi_clk = {
+	.halt_reg = 0x52058,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x52058,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_slave_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_tsctr_clk = {
+	.halt_reg = 0x52070,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(18),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_tsctr_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pcie_noc_xo_clk = {
+	.halt_reg = 0x52068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d018,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_pcie_noc_xo_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_pdm2_clk = {
+	.halt_reg = 0x1a00c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1a00c,
+		.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 = 0x1a004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1a004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1a004,
+		.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 = 0x1a008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1a008,
+		.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_qupv3_wrap3_core_2x_clk = {
+	.halt_reg = 0x23020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d000,
+		.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 = 0x2300c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d000,
+		.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_m_clk = {
+	.halt_reg = 0x23004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d000,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_m_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_qspi_ref_clk = {
+	.halt_reg = 0x23170,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d000,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_qspi_ref_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&gcc_qupv3_wrap3_qspi_ref_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 = 0x2315c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9d000,
+		.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_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_qupv3_wrap3_s_ahb_clk = {
+	.halt_reg = 0x23008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x9d010,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_qupv3_wrap3_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gcc_smmu_pcie_qtc_vote_clk = {
+	.halt_reg = 0x7d0b8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x7d0b8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gcc_smmu_pcie_qtc_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gcc_pcie_a_gdsc = {
+	.gdscr = 0x49004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(1),
+	.pd = {
+		.name = "gcc_pcie_a_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_a_phy_gdsc = {
+	.gdscr = 0x4d004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(5),
+	.pd = {
+		.name = "gcc_pcie_a_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_b_gdsc = {
+	.gdscr = 0x4a004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(2),
+	.pd = {
+		.name = "gcc_pcie_b_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_b_phy_gdsc = {
+	.gdscr = 0x4e004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(6),
+	.pd = {
+		.name = "gcc_pcie_b_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_c_gdsc = {
+	.gdscr = 0x4b004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(3),
+	.pd = {
+		.name = "gcc_pcie_c_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_c_phy_gdsc = {
+	.gdscr = 0x4f004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(7),
+	.pd = {
+		.name = "gcc_pcie_c_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_d_gdsc = {
+	.gdscr = 0x4c004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(4),
+	.pd = {
+		.name = "gcc_pcie_d_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_d_phy_gdsc = {
+	.gdscr = 0x50004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(8),
+	.pd = {
+		.name = "gcc_pcie_d_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct gdsc gcc_pcie_noc_gdsc = {
+	.gdscr = 0x52004,
+	.gds_hw_ctrl = 0x52018,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.collapse_ctrl = 0x8d02c,
+	.collapse_mask = BIT(0),
+	.pd = {
+		.name = "gcc_pcie_noc_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct clk_regmap *gcc_nord_clocks[] = {
+	[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_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_GPLL0] = &gcc_gpll0.clkr,
+	[GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr,
+	[GCC_MMU_0_TCU_VOTE_CLK] = &gcc_mmu_0_tcu_vote_clk.clkr,
+	[GCC_PCIE_A_AUX_CLK] = &gcc_pcie_a_aux_clk.clkr,
+	[GCC_PCIE_A_AUX_CLK_SRC] = &gcc_pcie_a_aux_clk_src.clkr,
+	[GCC_PCIE_A_CFG_AHB_CLK] = &gcc_pcie_a_cfg_ahb_clk.clkr,
+	[GCC_PCIE_A_DTI_QTC_CLK] = &gcc_pcie_a_dti_qtc_clk.clkr,
+	[GCC_PCIE_A_MSTR_AXI_CLK] = &gcc_pcie_a_mstr_axi_clk.clkr,
+	[GCC_PCIE_A_PHY_AUX_CLK] = &gcc_pcie_a_phy_aux_clk.clkr,
+	[GCC_PCIE_A_PHY_AUX_CLK_SRC] = &gcc_pcie_a_phy_aux_clk_src.clkr,
+	[GCC_PCIE_A_PHY_RCHNG_CLK] = &gcc_pcie_a_phy_rchng_clk.clkr,
+	[GCC_PCIE_A_PHY_RCHNG_CLK_SRC] = &gcc_pcie_a_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_A_PIPE_CLK] = &gcc_pcie_a_pipe_clk.clkr,
+	[GCC_PCIE_A_PIPE_CLK_SRC] = &gcc_pcie_a_pipe_clk_src.clkr,
+	[GCC_PCIE_A_SLV_AXI_CLK] = &gcc_pcie_a_slv_axi_clk.clkr,
+	[GCC_PCIE_A_SLV_Q2A_AXI_CLK] = &gcc_pcie_a_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_B_AUX_CLK] = &gcc_pcie_b_aux_clk.clkr,
+	[GCC_PCIE_B_AUX_CLK_SRC] = &gcc_pcie_b_aux_clk_src.clkr,
+	[GCC_PCIE_B_CFG_AHB_CLK] = &gcc_pcie_b_cfg_ahb_clk.clkr,
+	[GCC_PCIE_B_DTI_QTC_CLK] = &gcc_pcie_b_dti_qtc_clk.clkr,
+	[GCC_PCIE_B_MSTR_AXI_CLK] = &gcc_pcie_b_mstr_axi_clk.clkr,
+	[GCC_PCIE_B_PHY_AUX_CLK] = &gcc_pcie_b_phy_aux_clk.clkr,
+	[GCC_PCIE_B_PHY_AUX_CLK_SRC] = &gcc_pcie_b_phy_aux_clk_src.clkr,
+	[GCC_PCIE_B_PHY_RCHNG_CLK] = &gcc_pcie_b_phy_rchng_clk.clkr,
+	[GCC_PCIE_B_PHY_RCHNG_CLK_SRC] = &gcc_pcie_b_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_B_PIPE_CLK] = &gcc_pcie_b_pipe_clk.clkr,
+	[GCC_PCIE_B_PIPE_CLK_SRC] = &gcc_pcie_b_pipe_clk_src.clkr,
+	[GCC_PCIE_B_SLV_AXI_CLK] = &gcc_pcie_b_slv_axi_clk.clkr,
+	[GCC_PCIE_B_SLV_Q2A_AXI_CLK] = &gcc_pcie_b_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_C_AUX_CLK] = &gcc_pcie_c_aux_clk.clkr,
+	[GCC_PCIE_C_AUX_CLK_SRC] = &gcc_pcie_c_aux_clk_src.clkr,
+	[GCC_PCIE_C_CFG_AHB_CLK] = &gcc_pcie_c_cfg_ahb_clk.clkr,
+	[GCC_PCIE_C_DTI_QTC_CLK] = &gcc_pcie_c_dti_qtc_clk.clkr,
+	[GCC_PCIE_C_MSTR_AXI_CLK] = &gcc_pcie_c_mstr_axi_clk.clkr,
+	[GCC_PCIE_C_PHY_AUX_CLK] = &gcc_pcie_c_phy_aux_clk.clkr,
+	[GCC_PCIE_C_PHY_AUX_CLK_SRC] = &gcc_pcie_c_phy_aux_clk_src.clkr,
+	[GCC_PCIE_C_PHY_RCHNG_CLK] = &gcc_pcie_c_phy_rchng_clk.clkr,
+	[GCC_PCIE_C_PHY_RCHNG_CLK_SRC] = &gcc_pcie_c_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_C_PIPE_CLK] = &gcc_pcie_c_pipe_clk.clkr,
+	[GCC_PCIE_C_PIPE_CLK_SRC] = &gcc_pcie_c_pipe_clk_src.clkr,
+	[GCC_PCIE_C_SLV_AXI_CLK] = &gcc_pcie_c_slv_axi_clk.clkr,
+	[GCC_PCIE_C_SLV_Q2A_AXI_CLK] = &gcc_pcie_c_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_D_AUX_CLK] = &gcc_pcie_d_aux_clk.clkr,
+	[GCC_PCIE_D_AUX_CLK_SRC] = &gcc_pcie_d_aux_clk_src.clkr,
+	[GCC_PCIE_D_CFG_AHB_CLK] = &gcc_pcie_d_cfg_ahb_clk.clkr,
+	[GCC_PCIE_D_DTI_QTC_CLK] = &gcc_pcie_d_dti_qtc_clk.clkr,
+	[GCC_PCIE_D_MSTR_AXI_CLK] = &gcc_pcie_d_mstr_axi_clk.clkr,
+	[GCC_PCIE_D_PHY_AUX_CLK] = &gcc_pcie_d_phy_aux_clk.clkr,
+	[GCC_PCIE_D_PHY_AUX_CLK_SRC] = &gcc_pcie_d_phy_aux_clk_src.clkr,
+	[GCC_PCIE_D_PHY_RCHNG_CLK] = &gcc_pcie_d_phy_rchng_clk.clkr,
+	[GCC_PCIE_D_PHY_RCHNG_CLK_SRC] = &gcc_pcie_d_phy_rchng_clk_src.clkr,
+	[GCC_PCIE_D_PIPE_CLK] = &gcc_pcie_d_pipe_clk.clkr,
+	[GCC_PCIE_D_PIPE_CLK_SRC] = &gcc_pcie_d_pipe_clk_src.clkr,
+	[GCC_PCIE_D_SLV_AXI_CLK] = &gcc_pcie_d_slv_axi_clk.clkr,
+	[GCC_PCIE_D_SLV_Q2A_AXI_CLK] = &gcc_pcie_d_slv_q2a_axi_clk.clkr,
+	[GCC_PCIE_LINK_AHB_CLK] = &gcc_pcie_link_ahb_clk.clkr,
+	[GCC_PCIE_LINK_XO_CLK] = &gcc_pcie_link_xo_clk.clkr,
+	[GCC_PCIE_NOC_ASYNC_BRIDGE_CLK] = &gcc_pcie_noc_async_bridge_clk.clkr,
+	[GCC_PCIE_NOC_CNOC_SF_QX_CLK] = &gcc_pcie_noc_cnoc_sf_qx_clk.clkr,
+	[GCC_PCIE_NOC_M_CFG_CLK] = &gcc_pcie_noc_m_cfg_clk.clkr,
+	[GCC_PCIE_NOC_M_PDB_CLK] = &gcc_pcie_noc_m_pdb_clk.clkr,
+	[GCC_PCIE_NOC_MSTR_AXI_CLK] = &gcc_pcie_noc_mstr_axi_clk.clkr,
+	[GCC_PCIE_NOC_PWRCTL_CLK] = &gcc_pcie_noc_pwrctl_clk.clkr,
+	[GCC_PCIE_NOC_QOSGEN_EXTREF_CLK] = &gcc_pcie_noc_qosgen_extref_clk.clkr,
+	[GCC_PCIE_NOC_REFGEN_CLK] = &gcc_pcie_noc_refgen_clk.clkr,
+	[GCC_PCIE_NOC_REFGEN_CLK_SRC] = &gcc_pcie_noc_refgen_clk_src.clkr,
+	[GCC_PCIE_NOC_S_CFG_CLK] = &gcc_pcie_noc_s_cfg_clk.clkr,
+	[GCC_PCIE_NOC_S_PDB_CLK] = &gcc_pcie_noc_s_pdb_clk.clkr,
+	[GCC_PCIE_NOC_SAFETY_CLK] = &gcc_pcie_noc_safety_clk.clkr,
+	[GCC_PCIE_NOC_SAFETY_CLK_SRC] = &gcc_pcie_noc_safety_clk_src.clkr,
+	[GCC_PCIE_NOC_SLAVE_AXI_CLK] = &gcc_pcie_noc_slave_axi_clk.clkr,
+	[GCC_PCIE_NOC_TSCTR_CLK] = &gcc_pcie_noc_tsctr_clk.clkr,
+	[GCC_PCIE_NOC_XO_CLK] = &gcc_pcie_noc_xo_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_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_M_CLK] = &gcc_qupv3_wrap3_m_clk.clkr,
+	[GCC_QUPV3_WRAP3_QSPI_REF_CLK] = &gcc_qupv3_wrap3_qspi_ref_clk.clkr,
+	[GCC_QUPV3_WRAP3_QSPI_REF_CLK_SRC] = &gcc_qupv3_wrap3_qspi_ref_clk_src.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_S_AHB_CLK] = &gcc_qupv3_wrap3_s_ahb_clk.clkr,
+	[GCC_SMMU_PCIE_QTC_VOTE_CLK] = &gcc_smmu_pcie_qtc_vote_clk.clkr,
+};
+
+static struct gdsc *gcc_nord_gdscs[] = {
+	[GCC_PCIE_A_GDSC] = &gcc_pcie_a_gdsc,
+	[GCC_PCIE_A_PHY_GDSC] = &gcc_pcie_a_phy_gdsc,
+	[GCC_PCIE_B_GDSC] = &gcc_pcie_b_gdsc,
+	[GCC_PCIE_B_PHY_GDSC] = &gcc_pcie_b_phy_gdsc,
+	[GCC_PCIE_C_GDSC] = &gcc_pcie_c_gdsc,
+	[GCC_PCIE_C_PHY_GDSC] = &gcc_pcie_c_phy_gdsc,
+	[GCC_PCIE_D_GDSC] = &gcc_pcie_d_gdsc,
+	[GCC_PCIE_D_PHY_GDSC] = &gcc_pcie_d_phy_gdsc,
+	[GCC_PCIE_NOC_GDSC] = &gcc_pcie_noc_gdsc,
+};
+
+static const struct qcom_reset_map gcc_nord_resets[] = {
+	[GCC_PCIE_A_BCR] = { 0x49000 },
+	[GCC_PCIE_A_LINK_DOWN_BCR] = { 0xb9000 },
+	[GCC_PCIE_A_NOCSR_COM_PHY_BCR] = { 0xb900c },
+	[GCC_PCIE_A_PHY_BCR] = { 0x4d000 },
+	[GCC_PCIE_A_PHY_CFG_AHB_BCR] = { 0xb9014 },
+	[GCC_PCIE_A_PHY_COM_BCR] = { 0xb9018 },
+	[GCC_PCIE_A_PHY_NOCSR_COM_PHY_BCR] = { 0xb9010 },
+	[GCC_PCIE_B_BCR] = { 0x4a000 },
+	[GCC_PCIE_B_LINK_DOWN_BCR] = { 0xba000 },
+	[GCC_PCIE_B_NOCSR_COM_PHY_BCR] = { 0xba008 },
+	[GCC_PCIE_B_PHY_BCR] = { 0x4e000 },
+	[GCC_PCIE_B_PHY_CFG_AHB_BCR] = { 0xba010 },
+	[GCC_PCIE_B_PHY_COM_BCR] = { 0xba014 },
+	[GCC_PCIE_B_PHY_NOCSR_COM_PHY_BCR] = { 0xba00c },
+	[GCC_PCIE_C_BCR] = { 0x4b000 },
+	[GCC_PCIE_C_LINK_DOWN_BCR] = { 0xbb07c },
+	[GCC_PCIE_C_NOCSR_COM_PHY_BCR] = { 0xbb084 },
+	[GCC_PCIE_C_PHY_BCR] = { 0x4f000 },
+	[GCC_PCIE_C_PHY_CFG_AHB_BCR] = { 0xbb08c },
+	[GCC_PCIE_C_PHY_COM_BCR] = { 0xbb090 },
+	[GCC_PCIE_C_PHY_NOCSR_COM_PHY_BCR] = { 0xbb088 },
+	[GCC_PCIE_D_BCR] = { 0x4c000 },
+	[GCC_PCIE_D_LINK_DOWN_BCR] = { 0xbc000 },
+	[GCC_PCIE_D_NOCSR_COM_PHY_BCR] = { 0xbc008 },
+	[GCC_PCIE_D_PHY_BCR] = { 0x50000 },
+	[GCC_PCIE_D_PHY_CFG_AHB_BCR] = { 0xbc010 },
+	[GCC_PCIE_D_PHY_COM_BCR] = { 0xbc014 },
+	[GCC_PCIE_D_PHY_NOCSR_COM_PHY_BCR] = { 0xbc00c },
+	[GCC_PCIE_NOC_BCR] = { 0x52000 },
+	[GCC_PDM_BCR] = { 0x1a000 },
+	[GCC_QUPV3_WRAPPER_3_BCR] = { 0x23000 },
+	[GCC_TCSR_PCIE_BCR] = { 0xb901c },
+};
+
+static const struct clk_rcg_dfs_data gcc_nord_dfs_clocks[] = {
+	DEFINE_RCG_DFS(gcc_qupv3_wrap3_qspi_ref_clk_src),
+};
+
+static const struct regmap_config gcc_nord_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x1f41f0,
+	.fast_io = true,
+};
+
+static struct qcom_cc_driver_data gcc_nord_driver_data = {
+	.dfs_rcgs = gcc_nord_dfs_clocks,
+	.num_dfs_rcgs = ARRAY_SIZE(gcc_nord_dfs_clocks),
+};
+
+static const struct qcom_cc_desc gcc_nord_desc = {
+	.config = &gcc_nord_regmap_config,
+	.clks = gcc_nord_clocks,
+	.num_clks = ARRAY_SIZE(gcc_nord_clocks),
+	.resets = gcc_nord_resets,
+	.num_resets = ARRAY_SIZE(gcc_nord_resets),
+	.gdscs = gcc_nord_gdscs,
+	.num_gdscs = ARRAY_SIZE(gcc_nord_gdscs),
+	.use_rpm = true,
+	.driver_data = &gcc_nord_driver_data,
+};
+
+static const struct of_device_id gcc_nord_match_table[] = {
+	{ .compatible = "qcom,nord-gcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gcc_nord_match_table);
+
+static int gcc_nord_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &gcc_nord_desc);
+}
+
+static struct platform_driver gcc_nord_driver = {
+	.probe = gcc_nord_probe,
+	.driver = {
+		.name = "gcc-nord",
+		.of_match_table = gcc_nord_match_table,
+	},
+};
+
+static int __init gcc_nord_init(void)
+{
+	return platform_driver_register(&gcc_nord_driver);
+}
+subsys_initcall(gcc_nord_init);
+
+static void __exit gcc_nord_exit(void)
+{
+	platform_driver_unregister(&gcc_nord_driver);
+}
+module_exit(gcc_nord_exit);
+
+MODULE_DESCRIPTION("QTI GCC NORD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gcc-sc8180x.c b/drivers/clk/qcom/gcc-sc8180x.c
index 31e788e..e6b7f1a 100644
--- a/drivers/clk/qcom/gcc-sc8180x.c
+++ b/drivers/clk/qcom/gcc-sc8180x.c
@@ -4172,7 +4172,7 @@ static struct gdsc usb30_sec_gdsc = {
 	.pd = {
 		.name = "usb30_sec_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4190,7 +4190,7 @@ static struct gdsc usb30_prim_gdsc = {
 	.pd = {
 		.name = "usb30_prim_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4199,7 +4199,7 @@ static struct gdsc pcie_0_gdsc = {
 	.pd = {
 		.name = "pcie_0_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4226,7 +4226,7 @@ static struct gdsc pcie_1_gdsc = {
 	.pd = {
 		.name = "pcie_1_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4235,7 +4235,7 @@ static struct gdsc pcie_2_gdsc = {
 	.pd = {
 		.name = "pcie_2_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4253,7 +4253,7 @@ static struct gdsc pcie_3_gdsc = {
 	.pd = {
 		.name = "pcie_3_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
@@ -4262,10 +4262,55 @@ static struct gdsc usb30_mp_gdsc = {
 	.pd = {
 		.name = "usb30_mp_gdsc",
 	},
-	.pwrsts = PWRSTS_OFF_ON,
+	.pwrsts = PWRSTS_RET_ON,
 	.flags = POLL_CFG_GDSCR,
 };
 
+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_hf1_gdsc = {
+	.gdscr = 0x7d058,
+	.pd = {
+		.name = "hlos1_vote_mmnoc_mmu_tbu_hf1_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_turing_mmu_tbu0_gdsc = {
+	.gdscr = 0x7d05c,
+	.pd = {
+		.name = "hlos1_vote_turing_mmu_tbu0_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
+static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = {
+	.gdscr = 0x7d060,
+	.pd = {
+		.name = "hlos1_vote_turing_mmu_tbu1_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = VOTABLE,
+};
+
 static struct clk_regmap *gcc_sc8180x_clocks[] = {
 	[GCC_AGGRE_NOC_PCIE_TBU_CLK] = &gcc_aggre_noc_pcie_tbu_clk.clkr,
 	[GCC_AGGRE_UFS_CARD_AXI_CLK] = &gcc_aggre_ufs_card_axi_clk.clkr,
@@ -4560,7 +4605,7 @@ static const struct qcom_reset_map gcc_sc8180x_resets[] = {
 	[GCC_VIDEO_AXI1_CLK_BCR] = { .reg = 0xb028, .bit = 2, .udelay = 150 },
 };
 
-static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
+static const struct clk_rcg_dfs_data gcc_sc8180x_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),
@@ -4595,6 +4640,24 @@ static struct gdsc *gcc_sc8180x_gdscs[] = {
 	[USB30_MP_GDSC] = &usb30_mp_gdsc,
 	[USB30_PRIM_GDSC] = &usb30_prim_gdsc,
 	[USB30_SEC_GDSC] = &usb30_sec_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc,
+	[HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf_gdsc,
+	[HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc,
+	[HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc,
+};
+
+static const u32 gcc_sc8180x_critical_cbcrs[] = {
+	0xb004,  /* GCC_VIDEO_AHB_CLK */
+	0xb008,  /* GCC_CAMERA_AHB_CLK */
+	0xb00c,  /* GCC_DISP_AHB_CLK */
+	0xb040,  /* GCC_VIDEO_XO_CLK */
+	0xb044,  /* GCC_CAMERA_XO_CLK */
+	0xb048,  /* GCC_DISP_XO_CLK */
+	0x48004, /* GCC_CPUSS_GNOC_CLK */
+	0x48190, /* GCC_CPUSS_DVM_BUS_CLK */
+	0x4d004, /* GCC_NPU_CFG_AHB_CLK */
+	0x71004, /* GCC_GPU_CFG_AHB_CLK */
 };
 
 static const struct regmap_config gcc_sc8180x_regmap_config = {
@@ -4605,6 +4668,21 @@ static const struct regmap_config gcc_sc8180x_regmap_config = {
 	.fast_io	= true,
 };
 
+static void clk_sc8180x_regs_configure(struct device *dev, struct regmap *regmap)
+{
+	/* Disable the GPLL0 active input to NPU and GPU via MISC registers */
+	regmap_update_bits(regmap, 0x4d110, 0x3, 0x3);
+	regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
+}
+
+static const struct qcom_cc_driver_data gcc_sc8180x_driver_data = {
+	.clk_cbcrs = gcc_sc8180x_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(gcc_sc8180x_critical_cbcrs),
+	.dfs_rcgs = gcc_sc8180x_dfs_clocks,
+	.num_dfs_rcgs = ARRAY_SIZE(gcc_sc8180x_dfs_clocks),
+	.clk_regs_configure = clk_sc8180x_regs_configure,
+};
+
 static const struct qcom_cc_desc gcc_sc8180x_desc = {
 	.config = &gcc_sc8180x_regmap_config,
 	.clks = gcc_sc8180x_clocks,
@@ -4613,6 +4691,8 @@ static const struct qcom_cc_desc gcc_sc8180x_desc = {
 	.num_resets = ARRAY_SIZE(gcc_sc8180x_resets),
 	.gdscs = gcc_sc8180x_gdscs,
 	.num_gdscs = ARRAY_SIZE(gcc_sc8180x_gdscs),
+	.use_rpm = true,
+	.driver_data = &gcc_sc8180x_driver_data,
 };
 
 static const struct of_device_id gcc_sc8180x_match_table[] = {
@@ -4623,35 +4703,7 @@ MODULE_DEVICE_TABLE(of, gcc_sc8180x_match_table);
 
 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))
-		return PTR_ERR(regmap);
-
-	/* Keep some clocks always-on */
-	qcom_branch_set_clk_en(regmap, 0xb004); /* GCC_VIDEO_AHB_CLK */
-	qcom_branch_set_clk_en(regmap, 0xb008); /* GCC_CAMERA_AHB_CLK */
-	qcom_branch_set_clk_en(regmap, 0xb00c); /* GCC_DISP_AHB_CLK */
-	qcom_branch_set_clk_en(regmap, 0xb040); /* GCC_VIDEO_XO_CLK */
-	qcom_branch_set_clk_en(regmap, 0xb044); /* GCC_CAMERA_XO_CLK */
-	qcom_branch_set_clk_en(regmap, 0xb048); /* GCC_DISP_XO_CLK */
-	qcom_branch_set_clk_en(regmap, 0x48004); /* GCC_CPUSS_GNOC_CLK */
-	qcom_branch_set_clk_en(regmap, 0x48190); /* GCC_CPUSS_DVM_BUS_CLK */
-	qcom_branch_set_clk_en(regmap, 0x4d004); /* GCC_NPU_CFG_AHB_CLK */
-	qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */
-
-	/* Disable the GPLL0 active input to NPU and GPU via MISC registers */
-	regmap_update_bits(regmap, 0x4d110, 0x3, 0x3);
-	regmap_update_bits(regmap, 0x71028, 0x3, 0x3);
-
-	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);
+	return qcom_cc_probe(pdev, &gcc_sc8180x_desc);
 }
 
 static struct platform_driver gcc_sc8180x_driver = {
diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c
index 74afd12c1..73a2a51 100644
--- a/drivers/clk/qcom/gcc-x1e80100.c
+++ b/drivers/clk/qcom/gcc-x1e80100.c
@@ -7480,6 +7480,7 @@ static int gcc_x1e80100_probe(struct platform_device *pdev)
 	qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_VIDEO_AHB_CLK */
 	qcom_branch_set_clk_en(regmap, 0x32030); /* GCC_VIDEO_XO_CLK */
 	qcom_branch_set_clk_en(regmap, 0x71004); /* GCC_GPU_CFG_AHB_CLK */
+	qcom_branch_set_clk_en(regmap, 0x7d01c); /* GCC_HLOS1_VOTE_AGGRE_NOC_MMU_USB_QTB_CLK */
 
 	/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
 	regmap_write(regmap, 0x52224, 0x0);
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
index 7deabf8..95aa071 100644
--- a/drivers/clk/qcom/gdsc.c
+++ b/drivers/clk/qcom/gdsc.c
@@ -518,10 +518,20 @@ static int gdsc_add_subdomain_list(struct dev_pm_domain_list *pd_list,
 
 		ret = pm_genpd_add_subdomain(genpd, subdomain);
 		if (ret)
-			return ret;
+			goto remove_added_subdomains;
 	}
 
 	return 0;
+
+remove_added_subdomains:
+	for (i--; i >= 0; i--) {
+		struct device *dev = pd_list->pd_devs[i];
+		struct generic_pm_domain *genpd = pd_to_genpd(dev->pm_domain);
+
+		pm_genpd_remove_subdomain(genpd, subdomain);
+	}
+
+	return ret;
 }
 
 static void gdsc_remove_subdomain_list(struct dev_pm_domain_list *pd_list,
diff --git a/drivers/clk/qcom/gpucc-glymur.c b/drivers/clk/qcom/gpucc-glymur.c
new file mode 100644
index 0000000..54cc312
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-glymur.c
@@ -0,0 +1,618 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,glymur-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_OUT_EVEN,
+	P_GPU_CC_PLL0_OUT_MAIN,
+	P_GPU_CC_PLL0_OUT_ODD,
+};
+
+static const struct pll_vco taycan_eko_t_vco[] = {
+	{ 249600000, 2500000000, 0 },
+};
+
+/* 1150.0 MHz Configuration */
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x3b,
+	.alpha = 0xe555,
+	.config_ctl_val = 0x25c400e7,
+	.config_ctl_hi_val = 0x0a8060e0,
+	.config_ctl_hi1_val = 0xf51dea20,
+	.user_ctl_val = 0x00000408,
+	.user_ctl_hi_val = 0x00000002,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.config = &gpu_cc_pll0_config,
+	.vco_table = taycan_eko_t_vco,
+	.num_vco = ARRAY_SIZE(taycan_eko_t_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
+	.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_taycan_eko_t_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_gpu_cc_pll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_pll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_taycan_eko_t_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_PLL0_OUT_EVEN, 2 },
+	{ P_GPU_CC_PLL0_OUT_ODD, 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_pll0_out_even.clkr.hw },
+	{ .hw = &gpu_cc_pll0.clkr.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+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_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(575000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	F(700000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	F(725000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	F(750000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 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 const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+	F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_hub_clk_src = {
+	.cmd_rcgr = 0x93f0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_hub_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_hub_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_regmap_div gpu_cc_hub_div_clk_src = {
+	.reg = 0x9430,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_hub_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_hub_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 = 0x90bc,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x90bc,
+		.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_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_accu_shift_clk = {
+	.halt_reg = 0x9108,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9108,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_accu_shift_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_ff_clk = {
+	.halt_reg = 0x90ec,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x90ec,
+		.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 = 0x90d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90d4,
+		.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_clk = {
+	.halt_reg = 0x90e4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x90e4,
+		.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_demet_clk = {
+	.halt_reg = 0x9010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_demet_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_dpm_clk = {
+	.halt_reg = 0x910c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x910c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_dpm_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_freq_measure_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_freq_measure_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gpu_smmu_vote_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_gpu_smmu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_accu_shift_clk = {
+	.halt_reg = 0x9070,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_accu_shift_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_acd_ahb_ff_clk = {
+	.halt_reg = 0x9068,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_acd_ahb_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_gx_ahb_ff_clk = {
+	.halt_reg = 0x9064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_ahb_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_gx_gmu_clk = {
+	.halt_reg = 0x9060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9060,
+		.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_rcg_ahb_ff_clk = {
+	.halt_reg = 0x906c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x906c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_rcg_ahb_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_hub_aon_clk = {
+	.halt_reg = 0x93ec,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x93ec,
+		.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 = 0x90e8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90e8,
+		.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 = 0x90f0,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90f0,
+		.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_rscc_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_rscc_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_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_sleep_clk = {
+	.halt_reg = 0x90cc,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x90cc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gpu_cc_cx_gdsc = {
+	.gdscr = 0x9080,
+	.gds_hw_ctrl = 0x9094,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "gpu_cc_cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *gpu_cc_glymur_clocks[] = {
+	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+	[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_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_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr,
+	[GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.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_GPU_SMMU_VOTE_CLK] = &gpu_cc_gpu_smmu_vote_clk.clkr,
+	[GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr,
+	[GPU_CC_GX_ACD_AHB_FF_CLK] = &gpu_cc_gx_acd_ahb_ff_clk.clkr,
+	[GPU_CC_GX_AHB_FF_CLK] = &gpu_cc_gx_ahb_ff_clk.clkr,
+	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
+	[GPU_CC_GX_RCG_AHB_FF_CLK] = &gpu_cc_gx_rcg_ahb_ff_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_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr,
+	[GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
+	[GPU_CC_RSCC_HUB_AON_CLK] = &gpu_cc_rscc_hub_aon_clk.clkr,
+	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
+};
+
+static struct gdsc *gpu_cc_glymur_gdscs[] = {
+	[GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc,
+};
+
+static const struct qcom_reset_map gpu_cc_glymur_resets[] = {
+	[GPU_CC_CB_BCR] = { 0x93a0 },
+	[GPU_CC_CX_BCR] = { 0x907c },
+	[GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
+	[GPU_CC_FF_BCR] = { 0x9470 },
+	[GPU_CC_GMU_BCR] = { 0x9314 },
+	[GPU_CC_GX_BCR] = { 0x905c },
+	[GPU_CC_XO_BCR] = { 0x9000 },
+};
+
+static struct clk_alpha_pll *gpu_cc_glymur_plls[] = {
+	&gpu_cc_pll0,
+};
+
+static const u32 gpu_cc_glymur_critical_cbcrs[] = {
+	0x93a4, /* GPU_CC_CB_CLK */
+	0x9008, /* GPU_CC_CXO_AON_CLK */
+	0x9004, /* GPU_CC_RSCC_XO_AON_CLK */
+};
+
+static const struct regmap_config gpu_cc_glymur_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x95e8,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_driver_data gpu_cc_glymur_driver_data = {
+	.alpha_plls = gpu_cc_glymur_plls,
+	.num_alpha_plls = ARRAY_SIZE(gpu_cc_glymur_plls),
+	.clk_cbcrs = gpu_cc_glymur_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(gpu_cc_glymur_critical_cbcrs),
+};
+
+static const struct qcom_cc_desc gpu_cc_glymur_desc = {
+	.config = &gpu_cc_glymur_regmap_config,
+	.clks = gpu_cc_glymur_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_glymur_clocks),
+	.resets = gpu_cc_glymur_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_glymur_resets),
+	.gdscs = gpu_cc_glymur_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_glymur_gdscs),
+	.use_rpm = true,
+	.driver_data = &gpu_cc_glymur_driver_data,
+};
+
+static const struct of_device_id gpu_cc_glymur_match_table[] = {
+	{ .compatible = "qcom,glymur-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_glymur_match_table);
+
+static int gpu_cc_glymur_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &gpu_cc_glymur_desc);
+}
+
+static struct platform_driver gpu_cc_glymur_driver = {
+	.probe = gpu_cc_glymur_probe,
+	.driver = {
+		.name = "gpucc-glymur",
+		.of_match_table = gpu_cc_glymur_match_table,
+	},
+};
+
+module_platform_driver(gpu_cc_glymur_driver);
+
+MODULE_DESCRIPTION("QTI GPUCC Glymur Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gpucc-kaanapali.c b/drivers/clk/qcom/gpucc-kaanapali.c
index 52be48c..7f6013b 100644
--- a/drivers/clk/qcom/gpucc-kaanapali.c
+++ b/drivers/clk/qcom/gpucc-kaanapali.c
@@ -6,7 +6,6 @@
 #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>
 
@@ -424,7 +423,7 @@ static struct clk_alpha_pll *gpu_cc_kaanapali_plls[] = {
 	&gpu_cc_pll0,
 };
 
-static u32 gpu_cc_kaanapali_critical_cbcrs[] = {
+static const u32 gpu_cc_kaanapali_critical_cbcrs[] = {
 	0x9008, /* GPU_CC_CXO_AON_CLK */
 	0x93e8, /* GPU_CC_RSCC_HUB_AON_CLK */
 	0x9004, /* GPU_CC_RSCC_XO_AON_CLK */
@@ -438,7 +437,7 @@ static const struct regmap_config gpu_cc_kaanapali_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data gpu_cc_kaanapali_driver_data = {
+static const struct qcom_cc_driver_data gpu_cc_kaanapali_driver_data = {
 	.alpha_plls = gpu_cc_kaanapali_plls,
 	.num_alpha_plls = ARRAY_SIZE(gpu_cc_kaanapali_plls),
 	.clk_cbcrs = gpu_cc_kaanapali_critical_cbcrs,
diff --git a/drivers/clk/qcom/gpucc-milos.c b/drivers/clk/qcom/gpucc-milos.c
index 4ee0987..1448d95 100644
--- a/drivers/clk/qcom/gpucc-milos.c
+++ b/drivers/clk/qcom/gpucc-milos.c
@@ -500,7 +500,7 @@ static struct clk_alpha_pll *gpu_cc_milos_plls[] = {
 	&gpu_cc_pll0,
 };
 
-static u32 gpu_cc_milos_critical_cbcrs[] = {
+static const u32 gpu_cc_milos_critical_cbcrs[] = {
 	0x93a4, /* GPU_CC_CB_CLK */
 	0x9008, /* GPU_CC_CXO_AON_CLK */
 	0x9010, /* GPU_CC_DEMET_CLK */
@@ -518,7 +518,7 @@ static const struct regmap_config gpu_cc_milos_regmap_config = {
 	.fast_io = true,
 };
 
-static struct qcom_cc_driver_data gpu_cc_milos_driver_data = {
+static const struct qcom_cc_driver_data gpu_cc_milos_driver_data = {
 	.alpha_plls = gpu_cc_milos_plls,
 	.num_alpha_plls = ARRAY_SIZE(gpu_cc_milos_plls),
 	.clk_cbcrs = gpu_cc_milos_critical_cbcrs,
diff --git a/drivers/clk/qcom/gpucc-qcs615.c b/drivers/clk/qcom/gpucc-qcs615.c
index ec6739c..91919cd 100644
--- a/drivers/clk/qcom/gpucc-qcs615.c
+++ b/drivers/clk/qcom/gpucc-qcs615.c
@@ -459,7 +459,7 @@ static struct clk_alpha_pll *gpu_cc_qcs615_plls[] = {
 	&gpu_cc_pll1,
 };
 
-static u32 gpu_cc_qcs615_critical_cbcrs[] = {
+static const u32 gpu_cc_qcs615_critical_cbcrs[] = {
 	0x1078, /* GPU_CC_AHB_CLK */
 };
 
@@ -485,7 +485,7 @@ static void clk_qcs615_regs_crc_configure(struct device *dev, struct regmap *reg
 	regmap_update_bits(regmap, 0x1024, 0x00800000, 0x00800000);
 }
 
-static struct qcom_cc_driver_data gpu_cc_qcs615_driver_data = {
+static const struct qcom_cc_driver_data gpu_cc_qcs615_driver_data = {
 	.alpha_plls = gpu_cc_qcs615_plls,
 	.num_alpha_plls = ARRAY_SIZE(gpu_cc_qcs615_plls),
 	.clk_cbcrs = gpu_cc_qcs615_critical_cbcrs,
diff --git a/drivers/clk/qcom/gpucc-sm8750.c b/drivers/clk/qcom/gpucc-sm8750.c
new file mode 100644
index 0000000..5d52c6d
--- /dev/null
+++ b/drivers/clk/qcom/gpucc-sm8750.c
@@ -0,0 +1,473 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#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,sm8750-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_EVEN,
+	P_GPU_CC_PLL0_OUT_MAIN,
+	P_GPU_CC_PLL0_OUT_ODD,
+};
+
+static const struct pll_vco taycan_elu_vco[] = {
+	{ 249600000, 2500000000, 0 },
+};
+
+static const struct alpha_pll_config gpu_cc_pll0_config = {
+	.l = 0x34,
+	.alpha = 0x1555,
+	.config_ctl_val = 0x19660387,
+	.config_ctl_hi_val = 0x098060a0,
+	.config_ctl_hi1_val = 0xb416cb20,
+	.user_ctl_val = 0x00000400,
+	.user_ctl_hi_val = 0x00000002,
+};
+
+static struct clk_alpha_pll gpu_cc_pll0 = {
+	.offset = 0x0,
+	.config = &gpu_cc_pll0_config,
+	.vco_table = taycan_elu_vco,
+	.num_vco = ARRAY_SIZE(taycan_elu_vco),
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU],
+	.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_taycan_elu_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_gpu_cc_pll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_pll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_pll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_alpha_pll_postdiv_taycan_elu_ops,
+	},
+};
+
+static const struct parent_map gpu_cc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
+	{ P_GPU_CC_PLL0_OUT_EVEN, 2 },
+	{ P_GPU_CC_PLL0_OUT_ODD, 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_pll0_out_even.clkr.hw },
+	{ .hw = &gpu_cc_pll0.clkr.hw },
+	{ .index = DT_GPLL0_OUT_MAIN },
+	{ .index = DT_GPLL0_OUT_MAIN_DIV },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(500000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
+	F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 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 const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
+	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+	F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 gpu_cc_hub_clk_src = {
+	.cmd_rcgr = 0x93ec,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = gpu_cc_parent_map_1,
+	.freq_tbl = ftbl_gpu_cc_hub_clk_src,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_hub_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_regmap_div gpu_cc_hub_div_clk_src = {
+	.reg = 0x942c,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "gpu_cc_hub_div_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&gpu_cc_hub_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 = 0x90bc,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x90bc,
+		.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_div_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_accu_shift_clk = {
+	.halt_reg = 0x910c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x910c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_cx_accu_shift_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+	.halt_reg = 0x90d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90d4,
+		.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_clk = {
+	.halt_reg = 0x90e4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x90e4,
+		.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_demet_clk = {
+	.halt_reg = 0x9010,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9010,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_demet_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_dpm_clk = {
+	.halt_reg = 0x9110,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9110,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_dpm_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_freq_measure_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_freq_measure_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_accu_shift_clk = {
+	.halt_reg = 0x9070,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x9070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_gx_accu_shift_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch gpu_cc_gx_gmu_clk = {
+	.halt_reg = 0x9060,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x9060,
+		.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 = 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_hub_aon_clk = {
+	.halt_reg = 0x93e8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.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 = 0x90e8,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90e8,
+		.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 = 0x90f4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x90f4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "gpu_cc_memnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc gpu_cc_cx_gdsc = {
+	.gdscr = 0x9080,
+	.gds_hw_ctrl = 0x9094,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x8,
+	.pd = {
+		.name = "gpu_cc_cx_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = RETAIN_FF_ENABLE | VOTABLE,
+};
+
+static struct clk_regmap *gpu_cc_sm8750_clocks[] = {
+	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
+	[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr,
+	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+	[GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr,
+	[GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.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_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.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_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_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr,
+	[GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
+	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
+	[GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
+};
+
+static struct gdsc *gpu_cc_sm8750_gdscs[] = {
+	[GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc,
+};
+
+static const struct qcom_reset_map gpu_cc_sm8750_resets[] = {
+	[GPU_CC_GPU_CC_XO_BCR] = { 0x9000 },
+	[GPU_CC_GPU_CC_GX_BCR] = { 0x905c },
+	[GPU_CC_GPU_CC_CX_BCR] = { 0x907c },
+	[GPU_CC_GPU_CC_GMU_BCR] = { 0x9314 },
+	[GPU_CC_GPU_CC_CB_BCR] = { 0x93a0 },
+	[GPU_CC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
+};
+
+static const struct regmap_config gpu_cc_sm8750_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0x9800,
+	.fast_io = true,
+};
+
+static struct clk_alpha_pll *gpu_cc_alpha_plls[] = {
+	&gpu_cc_pll0,
+};
+
+static u32 gpu_cc_sm8750_critical_cbcrs[] = {
+	0x9004, /* GPU_CC_RSCC_XO_AON_CLK */
+	0x9008, /* GPU_CC_CXO_AON_CLK */
+	0x9064, /* GPU_CC_GX_AHB_FF_CLK */
+	0x90cc, /* GPU_CC_SLEEP_CLK */
+	0x93a4, /* GPU_CC_CB_CLK */
+	0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */
+};
+
+static struct qcom_cc_driver_data gpu_cc_sm8750_driver_data = {
+	.alpha_plls = gpu_cc_alpha_plls,
+	.num_alpha_plls = ARRAY_SIZE(gpu_cc_alpha_plls),
+	.clk_cbcrs = gpu_cc_sm8750_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(gpu_cc_sm8750_critical_cbcrs),
+};
+
+static const struct qcom_cc_desc gpu_cc_sm8750_desc = {
+	.config = &gpu_cc_sm8750_regmap_config,
+	.clks = gpu_cc_sm8750_clocks,
+	.num_clks = ARRAY_SIZE(gpu_cc_sm8750_clocks),
+	.resets = gpu_cc_sm8750_resets,
+	.num_resets = ARRAY_SIZE(gpu_cc_sm8750_resets),
+	.gdscs = gpu_cc_sm8750_gdscs,
+	.num_gdscs = ARRAY_SIZE(gpu_cc_sm8750_gdscs),
+	.use_rpm = true,
+	.driver_data = &gpu_cc_sm8750_driver_data,
+};
+
+static const struct of_device_id gpu_cc_sm8750_match_table[] = {
+	{ .compatible = "qcom,sm8750-gpucc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sm8750_match_table);
+
+static int gpu_cc_sm8750_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &gpu_cc_sm8750_desc);
+}
+
+static struct platform_driver gpu_cc_sm8750_driver = {
+	.probe = gpu_cc_sm8750_probe,
+	.driver = {
+		.name = "sm8750-gpucc",
+		.of_match_table = gpu_cc_sm8750_match_table,
+	},
+};
+module_platform_driver(gpu_cc_sm8750_driver);
+
+MODULE_DESCRIPTION("QTI GPU_CC SM8750 Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c
index c209ce5..40d8563 100644
--- a/drivers/clk/qcom/gxclkctl-kaanapali.c
+++ b/drivers/clk/qcom/gxclkctl-kaanapali.c
@@ -6,7 +6,6 @@
 #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>
 
@@ -52,7 +51,9 @@ static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = {
 };
 
 static const struct of_device_id gx_clkctl_kaanapali_match_table[] = {
+	{ .compatible = "qcom,glymur-gxclkctl" },
 	{ .compatible = "qcom,kaanapali-gxclkctl" },
+	{ .compatible = "qcom,sm8750-gxclkctl" },
 	{ }
 };
 MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table);
diff --git a/drivers/clk/qcom/ipq-cmn-pll.c b/drivers/clk/qcom/ipq-cmn-pll.c
index dafbf57..5763e4d 100644
--- a/drivers/clk/qcom/ipq-cmn-pll.c
+++ b/drivers/clk/qcom/ipq-cmn-pll.c
@@ -52,6 +52,8 @@
 #include <dt-bindings/clock/qcom,ipq-cmn-pll.h>
 #include <dt-bindings/clock/qcom,ipq5018-cmn-pll.h>
 #include <dt-bindings/clock/qcom,ipq5424-cmn-pll.h>
+#include <dt-bindings/clock/qcom,ipq6018-cmn-pll.h>
+#include <dt-bindings/clock/qcom,ipq8074-cmn-pll.h>
 
 #define CMN_PLL_REFCLK_SRC_SELECTION		0x28
 #define CMN_PLL_REFCLK_SRC_DIV			GENMASK(9, 8)
@@ -117,6 +119,18 @@ static const struct cmn_pll_fixed_output_clk ipq5018_output_clks[] = {
 	{ /* Sentinel */ }
 };
 
+static const struct cmn_pll_fixed_output_clk ipq6018_output_clks[] = {
+	CLK_PLL_OUTPUT(IPQ6018_BIAS_PLL_CC_CLK, "bias_pll_cc_clk", 300000000UL),
+	CLK_PLL_OUTPUT(IPQ6018_BIAS_PLL_NSS_NOC_CLK, "bias_pll_nss_noc_clk", 416500000UL),
+	{ /* Sentinel */ }
+};
+
+static const struct cmn_pll_fixed_output_clk ipq8074_output_clks[] = {
+	CLK_PLL_OUTPUT(IPQ8074_BIAS_PLL_CC_CLK, "bias_pll_cc_clk", 300000000UL),
+	CLK_PLL_OUTPUT(IPQ8074_BIAS_PLL_NSS_NOC_CLK, "bias_pll_nss_noc_clk", 416500000UL),
+	{ /* Sentinel */ }
+};
+
 static const struct cmn_pll_fixed_output_clk ipq5424_output_clks[] = {
 	CLK_PLL_OUTPUT(IPQ5424_XO_24MHZ_CLK, "xo-24mhz", 24000000UL),
 	CLK_PLL_OUTPUT(IPQ5424_SLEEP_32KHZ_CLK, "sleep-32khz", 32000UL),
@@ -448,6 +462,8 @@ static const struct dev_pm_ops ipq_cmn_pll_pm_ops = {
 static const struct of_device_id ipq_cmn_pll_clk_ids[] = {
 	{ .compatible = "qcom,ipq5018-cmn-pll", .data = &ipq5018_output_clks },
 	{ .compatible = "qcom,ipq5424-cmn-pll", .data = &ipq5424_output_clks },
+	{ .compatible = "qcom,ipq6018-cmn-pll", .data = &ipq6018_output_clks },
+	{ .compatible = "qcom,ipq8074-cmn-pll", .data = &ipq8074_output_clks },
 	{ .compatible = "qcom,ipq9574-cmn-pll", .data = &ipq9574_output_clks },
 	{ }
 };
diff --git a/drivers/clk/qcom/negcc-nord.c b/drivers/clk/qcom/negcc-nord.c
new file mode 100644
index 0000000..1aa24e2
--- /dev/null
+++ b/drivers/clk/qcom/negcc-nord.c
@@ -0,0 +1,1987 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,nord-negcc.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_UFS_PHY_RX_SYMBOL_0_CLK,
+	DT_UFS_PHY_RX_SYMBOL_1_CLK,
+	DT_UFS_PHY_TX_SYMBOL_0_CLK,
+	DT_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK,
+	DT_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_NE_GCC_GPLL0_OUT_EVEN,
+	P_NE_GCC_GPLL0_OUT_MAIN,
+	P_NE_GCC_GPLL2_OUT_MAIN,
+	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_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK,
+	P_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK,
+};
+
+static struct clk_alpha_pll ne_gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_ne_gcc_gpll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv ne_gcc_gpll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_ne_gcc_gpll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_ne_gcc_gpll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_gpll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&ne_gcc_gpll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static struct clk_alpha_pll ne_gcc_gpll2 = {
+	.offset = 0x2000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct parent_map ne_gcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_NE_GCC_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &ne_gcc_gpll0.clkr.hw },
+};
+
+static const struct parent_map ne_gcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_NE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_NE_GCC_GPLL0_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &ne_gcc_gpll0.clkr.hw },
+	{ .hw = &ne_gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map ne_gcc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_NE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_NE_GCC_GPLL2_OUT_MAIN, 3 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &ne_gcc_gpll0.clkr.hw },
+	{ .hw = &ne_gcc_gpll2.clkr.hw },
+};
+
+static const struct parent_map ne_gcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map ne_gcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_NE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &ne_gcc_gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map ne_gcc_parent_map_5[] = {
+	{ P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_5[] = {
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map ne_gcc_parent_map_6[] = {
+	{ P_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_6[] = {
+	{ .index = DT_USB3_PHY_WRAPPER_NE_GCC_USB31_PIPE_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static const struct parent_map ne_gcc_parent_map_7[] = {
+	{ P_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK, 0 },
+	{ P_BI_TCXO, 2 },
+};
+
+static const struct clk_parent_data ne_gcc_parent_data_7[] = {
+	{ .index = DT_USB3_PHY_SEC_WRAPPER_NE_GCC_USB31_PIPE_CLK },
+	{ .index = DT_BI_TCXO },
+};
+
+static struct clk_regmap_phy_mux ne_gcc_ufs_phy_rx_symbol_0_clk_src = {
+	.reg = 0x33068,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_rx_symbol_0_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_RX_SYMBOL_0_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux ne_gcc_ufs_phy_rx_symbol_1_clk_src = {
+	.reg = 0x330f0,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_rx_symbol_1_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_RX_SYMBOL_1_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_phy_mux ne_gcc_ufs_phy_tx_symbol_0_clk_src = {
+	.reg = 0x33058,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_tx_symbol_0_clk_src",
+			.parent_data = &(const struct clk_parent_data){
+				.index = DT_UFS_PHY_TX_SYMBOL_0_CLK,
+			},
+			.num_parents = 1,
+			.ops = &clk_regmap_phy_mux_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux ne_gcc_usb3_prim_phy_pipe_clk_src = {
+	.reg = 0x2a078,
+	.shift = 0,
+	.width = 2,
+	.parent_map = ne_gcc_parent_map_6,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_prim_phy_pipe_clk_src",
+			.parent_data = ne_gcc_parent_data_6,
+			.num_parents = ARRAY_SIZE(ne_gcc_parent_data_6),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static struct clk_regmap_mux ne_gcc_usb3_sec_phy_pipe_clk_src = {
+	.reg = 0x2c078,
+	.shift = 0,
+	.width = 2,
+	.parent_map = ne_gcc_parent_map_7,
+	.clkr = {
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_sec_phy_pipe_clk_src",
+			.parent_data = ne_gcc_parent_data_7,
+			.num_parents = ARRAY_SIZE(ne_gcc_parent_data_7),
+			.ops = &clk_regmap_mux_closest_ops,
+		},
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_gp1_clk_src[] = {
+	F(66666667, P_NE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(100000000, P_NE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_NE_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_gp1_clk_src = {
+	.cmd_rcgr = 0x21004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_4,
+	.freq_tbl = ftbl_ne_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_gp1_clk_src",
+		.parent_data = ne_gcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x22004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_4,
+	.freq_tbl = ftbl_ne_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_gp2_clk_src",
+		.parent_data = ne_gcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_qupv3_wrap2_s0_clk_src[] = {
+	F(7372800, P_NE_GCC_GPLL0_OUT_MAIN, 1, 192, 15625),
+	F(14745600, P_NE_GCC_GPLL0_OUT_MAIN, 1, 384, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_NE_GCC_GPLL0_OUT_MAIN, 1, 768, 15625),
+	F(32000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 4, 75),
+	F(48000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 2, 25),
+	F(51200000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 32, 375),
+	F(64000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 8, 75),
+	F(66666667, P_NE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(75000000, P_NE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(80000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 2, 15),
+	F(96000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 4, 25),
+	F(100000000, P_NE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(102400000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 64, 375),
+	F(112000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 14, 75),
+	F(117964800, P_NE_GCC_GPLL0_OUT_MAIN, 1, 3072, 15625),
+	F(120000000, P_NE_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s0_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s0_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s0_clk_src = {
+	.cmd_rcgr = 0x3816c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s0_clk_src_init,
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s1_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s1_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s1_clk_src = {
+	.cmd_rcgr = 0x382a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s1_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_ne_gcc_qupv3_wrap2_s2_clk_src[] = {
+	F(7372800, P_NE_GCC_GPLL0_OUT_MAIN, 1, 192, 15625),
+	F(14745600, P_NE_GCC_GPLL0_OUT_MAIN, 1, 384, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_NE_GCC_GPLL0_OUT_MAIN, 1, 768, 15625),
+	F(32000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 4, 75),
+	F(48000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 2, 25),
+	F(51200000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 32, 375),
+	F(64000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 8, 75),
+	F(66666667, P_NE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(75000000, P_NE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(80000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 2, 15),
+	F(96000000, P_NE_GCC_GPLL0_OUT_MAIN, 1, 4, 25),
+	F(100000000, P_NE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s2_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s2_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s2_clk_src = {
+	.cmd_rcgr = 0x383e4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s2_clk_src_init,
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s3_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s3_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s3_clk_src = {
+	.cmd_rcgr = 0x38520,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s3_clk_src_init,
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s4_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s4_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s4_clk_src = {
+	.cmd_rcgr = 0x3865c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s4_clk_src_init,
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s5_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s5_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s5_clk_src = {
+	.cmd_rcgr = 0x38798,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s5_clk_src_init,
+};
+
+static struct clk_init_data ne_gcc_qupv3_wrap2_s6_clk_src_init = {
+	.name = "ne_gcc_qupv3_wrap2_s6_clk_src",
+	.parent_data = ne_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 ne_gcc_qupv3_wrap2_s6_clk_src = {
+	.cmd_rcgr = 0x388d4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_qupv3_wrap2_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &ne_gcc_qupv3_wrap2_s6_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_ne_gcc_sdcc4_apps_clk_src[] = {
+	F(37500000, P_NE_GCC_GPLL0_OUT_MAIN, 16, 0, 0),
+	F(50000000, P_NE_GCC_GPLL0_OUT_MAIN, 12, 0, 0),
+	F(100000000, P_NE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_sdcc4_apps_clk_src = {
+	.cmd_rcgr = 0x1801c,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_sdcc4_apps_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_sdcc4_apps_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_floor_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_ufs_phy_axi_clk_src[] = {
+	F(120000000, P_NE_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	F(201500000, P_NE_GCC_GPLL2_OUT_MAIN, 4, 0, 0),
+	F(300000000, P_NE_GCC_GPLL0_OUT_MAIN, 2, 0, 0),
+	F(403000000, P_NE_GCC_GPLL2_OUT_MAIN, 2, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_ufs_phy_axi_clk_src = {
+	.cmd_rcgr = 0x33034,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_2,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_axi_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_ufs_phy_axi_clk_src",
+		.parent_data = ne_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_ufs_phy_ice_core_clk_src = {
+	.cmd_rcgr = 0x3308c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_2,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_axi_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_ufs_phy_ice_core_clk_src",
+		.parent_data = ne_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_ufs_phy_phy_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_ufs_phy_phy_aux_clk_src = {
+	.cmd_rcgr = 0x330c0,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_5,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_ufs_phy_phy_aux_clk_src",
+		.parent_data = ne_gcc_parent_data_5,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_5),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_ufs_phy_unipro_core_clk_src = {
+	.cmd_rcgr = 0x330a4,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_2,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_axi_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_ufs_phy_unipro_core_clk_src",
+		.parent_data = ne_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_usb20_master_clk_src[] = {
+	F(75000000, P_NE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(120000000, P_NE_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_usb20_master_clk_src = {
+	.cmd_rcgr = 0x31030,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_usb20_master_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb20_master_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb20_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x31048,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb20_mock_utmi_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_ne_gcc_usb31_prim_master_clk_src[] = {
+	F(85714286, P_NE_GCC_GPLL0_OUT_MAIN, 7, 0, 0),
+	F(133333333, P_NE_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0),
+	F(200000000, P_NE_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	F(240000000, P_NE_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 ne_gcc_usb31_prim_master_clk_src = {
+	.cmd_rcgr = 0x2a038,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_1,
+	.freq_tbl = ftbl_ne_gcc_usb31_prim_master_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_prim_master_clk_src",
+		.parent_data = ne_gcc_parent_data_1,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_1),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb31_prim_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x2a050,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_prim_mock_utmi_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb31_sec_master_clk_src = {
+	.cmd_rcgr = 0x2c038,
+	.mnd_width = 8,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_usb31_prim_master_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_sec_master_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb31_sec_mock_utmi_clk_src = {
+	.cmd_rcgr = 0x2c050,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_0,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_sec_mock_utmi_clk_src",
+		.parent_data = ne_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb3_prim_phy_aux_clk_src = {
+	.cmd_rcgr = 0x2a07c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_3,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb3_prim_phy_aux_clk_src",
+		.parent_data = ne_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 ne_gcc_usb3_sec_phy_aux_clk_src = {
+	.cmd_rcgr = 0x2c07c,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = ne_gcc_parent_map_3,
+	.freq_tbl = ftbl_ne_gcc_ufs_phy_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb3_sec_phy_aux_clk_src",
+		.parent_data = ne_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(ne_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_regmap_div ne_gcc_usb20_mock_utmi_postdiv_clk_src = {
+	.reg = 0x31060,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb20_mock_utmi_postdiv_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&ne_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 ne_gcc_usb31_prim_mock_utmi_postdiv_clk_src = {
+	.reg = 0x2a068,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_prim_mock_utmi_postdiv_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&ne_gcc_usb31_prim_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 ne_gcc_usb31_sec_mock_utmi_postdiv_clk_src = {
+	.reg = 0x2c068,
+	.shift = 0,
+	.width = 4,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "ne_gcc_usb31_sec_mock_utmi_postdiv_clk_src",
+		.parent_hws = (const struct clk_hw*[]) {
+			&ne_gcc_usb31_sec_mock_utmi_clk_src.clkr.hw,
+		},
+		.num_parents = 1,
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_regmap_div_ro_ops,
+	},
+};
+
+static struct clk_branch ne_gcc_aggre_noc_ufs_phy_axi_clk = {
+	.halt_reg = 0x330f4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x330f4,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x330f4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_aggre_noc_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_aggre_noc_usb2_axi_clk = {
+	.halt_reg = 0x31068,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x31068,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x31068,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_aggre_noc_usb2_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_aggre_noc_usb3_prim_axi_clk = {
+	.halt_reg = 0x2a098,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2a098,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2a098,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_aggre_noc_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_aggre_noc_usb3_sec_axi_clk = {
+	.halt_reg = 0x2c098,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2c098,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2c098,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_aggre_noc_usb3_sec_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_ahb2phy_clk = {
+	.halt_reg = 0x30004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x30004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x30004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ahb2phy_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_cnoc_usb2_axi_clk = {
+	.halt_reg = 0x31064,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x31064,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x31064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_cnoc_usb2_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_cnoc_usb3_prim_axi_clk = {
+	.halt_reg = 0x2a094,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2a094,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2a094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_cnoc_usb3_prim_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_cnoc_usb3_sec_axi_clk = {
+	.halt_reg = 0x2c094,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2c094,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2c094,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_cnoc_usb3_sec_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_frq_measure_ref_clk = {
+	.halt_reg = 0x20008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x20008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_frq_measure_ref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gp1_clk = {
+	.halt_reg = 0x21000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x21000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_gp1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gp2_clk = {
+	.halt_reg = 0x22000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x22000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gp2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_gp2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gpu_2_cfg_clk = {
+	.halt_reg = 0x34004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x34004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x34004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpu_2_cfg_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gpu_2_gpll0_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpu_2_gpll0_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_gpll0.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gpu_2_gpll0_div_clk_src = {
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpu_2_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_gpll0_out_even.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gpu_2_hscnoc_gfx_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 = "ne_gcc_gpu_2_hscnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_gpu_2_smmu_vote_clk = {
+	.halt_reg = 0x57028,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_gpu_2_smmu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_core_2x_clk = {
+	.halt_reg = 0x38020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_core_clk = {
+	.halt_reg = 0x3800c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_m_ahb_clk = {
+	.halt_reg = 0x38004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x38004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(30),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s0_clk = {
+	.halt_reg = 0x3815c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s1_clk = {
+	.halt_reg = 0x38298,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(3),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s2_clk = {
+	.halt_reg = 0x383d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s3_clk = {
+	.halt_reg = 0x38510,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s4_clk = {
+	.halt_reg = 0x3864c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s5_clk = {
+	.halt_reg = 0x38788,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s6_clk = {
+	.halt_reg = 0x388c4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(8),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_qupv3_wrap2_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_qupv3_wrap2_s_ahb_clk = {
+	.halt_reg = 0x38008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x38008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(31),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_qupv3_wrap2_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_sdcc4_apps_clk = {
+	.halt_reg = 0x18004,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x18004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_sdcc4_apps_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_sdcc4_apps_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_sdcc4_axi_clk = {
+	.halt_reg = 0x18014,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x18014,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_sdcc4_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_ufs_phy_ahb_clk = {
+	.halt_reg = 0x33028,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x33028,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x33028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_ufs_phy_axi_clk = {
+	.halt_reg = 0x33018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x33018,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x33018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_axi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_ufs_phy_axi_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_ufs_phy_ice_core_clk = {
+	.halt_reg = 0x3307c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3307c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3307c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_ice_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_ufs_phy_phy_aux_clk = {
+	.halt_reg = 0x330bc,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x330bc,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x330bc,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_ufs_phy_rx_symbol_0_clk = {
+	.halt_reg = 0x33030,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x33030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_rx_symbol_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_ufs_phy_rx_symbol_1_clk = {
+	.halt_reg = 0x330d8,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x330d8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_rx_symbol_1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_ufs_phy_tx_symbol_0_clk = {
+	.halt_reg = 0x3302c,
+	.halt_check = BRANCH_HALT_DELAY,
+	.clkr = {
+		.enable_reg = 0x3302c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_tx_symbol_0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_ufs_phy_unipro_core_clk = {
+	.halt_reg = 0x3306c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x3306c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x3306c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_ufs_phy_unipro_core_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_usb20_master_clk = {
+	.halt_reg = 0x31018,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x31018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb20_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb20_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb20_mock_utmi_clk = {
+	.halt_reg = 0x3102c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x3102c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb20_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_usb20_sleep_clk = {
+	.halt_reg = 0x31028,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x31028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb20_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_prim_atb_clk = {
+	.halt_reg = 0x2a018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x2a018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_prim_atb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_prim_eud_ahb_clk = {
+	.halt_reg = 0x2a02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2a02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2a02c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_prim_eud_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_prim_master_clk = {
+	.halt_reg = 0x2a01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_prim_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_prim_mock_utmi_clk = {
+	.halt_reg = 0x2a034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_prim_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_mock_utmi_postdiv_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_prim_sleep_clk = {
+	.halt_reg = 0x2a030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_prim_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_sec_atb_clk = {
+	.halt_reg = 0x2c018,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x2c018,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_sec_atb_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_prim_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_sec_eud_ahb_clk = {
+	.halt_reg = 0x2c02c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2c02c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2c02c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_sec_eud_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_sec_master_clk = {
+	.halt_reg = 0x2c01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_sec_master_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_sec_master_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_sec_mock_utmi_clk = {
+	.halt_reg = 0x2c034,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_sec_mock_utmi_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb31_sec_mock_utmi_postdiv_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb31_sec_sleep_clk = {
+	.halt_reg = 0x2c030,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb31_sec_sleep_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb3_prim_phy_aux_clk = {
+	.halt_reg = 0x2a06c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a06c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_prim_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_usb3_prim_phy_com_aux_clk = {
+	.halt_reg = 0x2a070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2a070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_prim_phy_com_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_usb3_prim_phy_pipe_clk = {
+	.halt_reg = 0x2a074,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2a074,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2a074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_prim_phy_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_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 ne_gcc_usb3_sec_phy_aux_clk = {
+	.halt_reg = 0x2c06c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c06c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_sec_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb3_sec_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb3_sec_phy_com_aux_clk = {
+	.halt_reg = 0x2c070,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2c070,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_sec_phy_com_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb3_sec_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch ne_gcc_usb3_sec_phy_pipe_clk = {
+	.halt_reg = 0x2c074,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2c074,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2c074,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "ne_gcc_usb3_sec_phy_pipe_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&ne_gcc_usb3_sec_phy_pipe_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct gdsc ne_gcc_ufs_mem_phy_gdsc = {
+	.gdscr = 0x32000,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "ne_gcc_ufs_mem_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_ufs_phy_gdsc = {
+	.gdscr = 0x33004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ne_gcc_ufs_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_usb20_prim_gdsc = {
+	.gdscr = 0x31004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ne_gcc_usb20_prim_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_usb31_prim_gdsc = {
+	.gdscr = 0x2a004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ne_gcc_usb31_prim_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_usb31_sec_gdsc = {
+	.gdscr = 0x2c004,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0xf,
+	.pd = {
+		.name = "ne_gcc_usb31_sec_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_usb3_phy_gdsc = {
+	.gdscr = 0x2b00c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "ne_gcc_usb3_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct gdsc ne_gcc_usb3_sec_phy_gdsc = {
+	.gdscr = 0x2d00c,
+	.en_rest_wait_val = 0x2,
+	.en_few_wait_val = 0x2,
+	.clk_dis_wait_val = 0x2,
+	.pd = {
+		.name = "ne_gcc_usb3_sec_phy_gdsc",
+	},
+	.pwrsts = PWRSTS_OFF_ON,
+	.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
+};
+
+static struct clk_regmap *ne_gcc_nord_clocks[] = {
+	[NE_GCC_AGGRE_NOC_UFS_PHY_AXI_CLK] = &ne_gcc_aggre_noc_ufs_phy_axi_clk.clkr,
+	[NE_GCC_AGGRE_NOC_USB2_AXI_CLK] = &ne_gcc_aggre_noc_usb2_axi_clk.clkr,
+	[NE_GCC_AGGRE_NOC_USB3_PRIM_AXI_CLK] = &ne_gcc_aggre_noc_usb3_prim_axi_clk.clkr,
+	[NE_GCC_AGGRE_NOC_USB3_SEC_AXI_CLK] = &ne_gcc_aggre_noc_usb3_sec_axi_clk.clkr,
+	[NE_GCC_AHB2PHY_CLK] = &ne_gcc_ahb2phy_clk.clkr,
+	[NE_GCC_CNOC_USB2_AXI_CLK] = &ne_gcc_cnoc_usb2_axi_clk.clkr,
+	[NE_GCC_CNOC_USB3_PRIM_AXI_CLK] = &ne_gcc_cnoc_usb3_prim_axi_clk.clkr,
+	[NE_GCC_CNOC_USB3_SEC_AXI_CLK] = &ne_gcc_cnoc_usb3_sec_axi_clk.clkr,
+	[NE_GCC_FRQ_MEASURE_REF_CLK] = &ne_gcc_frq_measure_ref_clk.clkr,
+	[NE_GCC_GP1_CLK] = &ne_gcc_gp1_clk.clkr,
+	[NE_GCC_GP1_CLK_SRC] = &ne_gcc_gp1_clk_src.clkr,
+	[NE_GCC_GP2_CLK] = &ne_gcc_gp2_clk.clkr,
+	[NE_GCC_GP2_CLK_SRC] = &ne_gcc_gp2_clk_src.clkr,
+	[NE_GCC_GPLL0] = &ne_gcc_gpll0.clkr,
+	[NE_GCC_GPLL0_OUT_EVEN] = &ne_gcc_gpll0_out_even.clkr,
+	[NE_GCC_GPLL2] = &ne_gcc_gpll2.clkr,
+	[NE_GCC_GPU_2_CFG_CLK] = &ne_gcc_gpu_2_cfg_clk.clkr,
+	[NE_GCC_GPU_2_GPLL0_CLK_SRC] = &ne_gcc_gpu_2_gpll0_clk_src.clkr,
+	[NE_GCC_GPU_2_GPLL0_DIV_CLK_SRC] = &ne_gcc_gpu_2_gpll0_div_clk_src.clkr,
+	[NE_GCC_GPU_2_HSCNOC_GFX_CLK] = &ne_gcc_gpu_2_hscnoc_gfx_clk.clkr,
+	[NE_GCC_GPU_2_SMMU_VOTE_CLK] = &ne_gcc_gpu_2_smmu_vote_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_CORE_2X_CLK] = &ne_gcc_qupv3_wrap2_core_2x_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_CORE_CLK] = &ne_gcc_qupv3_wrap2_core_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_M_AHB_CLK] = &ne_gcc_qupv3_wrap2_m_ahb_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S0_CLK] = &ne_gcc_qupv3_wrap2_s0_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S0_CLK_SRC] = &ne_gcc_qupv3_wrap2_s0_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S1_CLK] = &ne_gcc_qupv3_wrap2_s1_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S1_CLK_SRC] = &ne_gcc_qupv3_wrap2_s1_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S2_CLK] = &ne_gcc_qupv3_wrap2_s2_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S2_CLK_SRC] = &ne_gcc_qupv3_wrap2_s2_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S3_CLK] = &ne_gcc_qupv3_wrap2_s3_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S3_CLK_SRC] = &ne_gcc_qupv3_wrap2_s3_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S4_CLK] = &ne_gcc_qupv3_wrap2_s4_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S4_CLK_SRC] = &ne_gcc_qupv3_wrap2_s4_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S5_CLK] = &ne_gcc_qupv3_wrap2_s5_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S5_CLK_SRC] = &ne_gcc_qupv3_wrap2_s5_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S6_CLK] = &ne_gcc_qupv3_wrap2_s6_clk.clkr,
+	[NE_GCC_QUPV3_WRAP2_S6_CLK_SRC] = &ne_gcc_qupv3_wrap2_s6_clk_src.clkr,
+	[NE_GCC_QUPV3_WRAP2_S_AHB_CLK] = &ne_gcc_qupv3_wrap2_s_ahb_clk.clkr,
+	[NE_GCC_SDCC4_APPS_CLK] = &ne_gcc_sdcc4_apps_clk.clkr,
+	[NE_GCC_SDCC4_APPS_CLK_SRC] = &ne_gcc_sdcc4_apps_clk_src.clkr,
+	[NE_GCC_SDCC4_AXI_CLK] = &ne_gcc_sdcc4_axi_clk.clkr,
+	[NE_GCC_UFS_PHY_AHB_CLK] = &ne_gcc_ufs_phy_ahb_clk.clkr,
+	[NE_GCC_UFS_PHY_AXI_CLK] = &ne_gcc_ufs_phy_axi_clk.clkr,
+	[NE_GCC_UFS_PHY_AXI_CLK_SRC] = &ne_gcc_ufs_phy_axi_clk_src.clkr,
+	[NE_GCC_UFS_PHY_ICE_CORE_CLK] = &ne_gcc_ufs_phy_ice_core_clk.clkr,
+	[NE_GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &ne_gcc_ufs_phy_ice_core_clk_src.clkr,
+	[NE_GCC_UFS_PHY_PHY_AUX_CLK] = &ne_gcc_ufs_phy_phy_aux_clk.clkr,
+	[NE_GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &ne_gcc_ufs_phy_phy_aux_clk_src.clkr,
+	[NE_GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &ne_gcc_ufs_phy_rx_symbol_0_clk.clkr,
+	[NE_GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &ne_gcc_ufs_phy_rx_symbol_0_clk_src.clkr,
+	[NE_GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &ne_gcc_ufs_phy_rx_symbol_1_clk.clkr,
+	[NE_GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &ne_gcc_ufs_phy_rx_symbol_1_clk_src.clkr,
+	[NE_GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &ne_gcc_ufs_phy_tx_symbol_0_clk.clkr,
+	[NE_GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &ne_gcc_ufs_phy_tx_symbol_0_clk_src.clkr,
+	[NE_GCC_UFS_PHY_UNIPRO_CORE_CLK] = &ne_gcc_ufs_phy_unipro_core_clk.clkr,
+	[NE_GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &ne_gcc_ufs_phy_unipro_core_clk_src.clkr,
+	[NE_GCC_USB20_MASTER_CLK] = &ne_gcc_usb20_master_clk.clkr,
+	[NE_GCC_USB20_MASTER_CLK_SRC] = &ne_gcc_usb20_master_clk_src.clkr,
+	[NE_GCC_USB20_MOCK_UTMI_CLK] = &ne_gcc_usb20_mock_utmi_clk.clkr,
+	[NE_GCC_USB20_MOCK_UTMI_CLK_SRC] = &ne_gcc_usb20_mock_utmi_clk_src.clkr,
+	[NE_GCC_USB20_MOCK_UTMI_POSTDIV_CLK_SRC] = &ne_gcc_usb20_mock_utmi_postdiv_clk_src.clkr,
+	[NE_GCC_USB20_SLEEP_CLK] = &ne_gcc_usb20_sleep_clk.clkr,
+	[NE_GCC_USB31_PRIM_ATB_CLK] = &ne_gcc_usb31_prim_atb_clk.clkr,
+	[NE_GCC_USB31_PRIM_EUD_AHB_CLK] = &ne_gcc_usb31_prim_eud_ahb_clk.clkr,
+	[NE_GCC_USB31_PRIM_MASTER_CLK] = &ne_gcc_usb31_prim_master_clk.clkr,
+	[NE_GCC_USB31_PRIM_MASTER_CLK_SRC] = &ne_gcc_usb31_prim_master_clk_src.clkr,
+	[NE_GCC_USB31_PRIM_MOCK_UTMI_CLK] = &ne_gcc_usb31_prim_mock_utmi_clk.clkr,
+	[NE_GCC_USB31_PRIM_MOCK_UTMI_CLK_SRC] = &ne_gcc_usb31_prim_mock_utmi_clk_src.clkr,
+	[NE_GCC_USB31_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] =
+		&ne_gcc_usb31_prim_mock_utmi_postdiv_clk_src.clkr,
+	[NE_GCC_USB31_PRIM_SLEEP_CLK] = &ne_gcc_usb31_prim_sleep_clk.clkr,
+	[NE_GCC_USB31_SEC_ATB_CLK] = &ne_gcc_usb31_sec_atb_clk.clkr,
+	[NE_GCC_USB31_SEC_EUD_AHB_CLK] = &ne_gcc_usb31_sec_eud_ahb_clk.clkr,
+	[NE_GCC_USB31_SEC_MASTER_CLK] = &ne_gcc_usb31_sec_master_clk.clkr,
+	[NE_GCC_USB31_SEC_MASTER_CLK_SRC] = &ne_gcc_usb31_sec_master_clk_src.clkr,
+	[NE_GCC_USB31_SEC_MOCK_UTMI_CLK] = &ne_gcc_usb31_sec_mock_utmi_clk.clkr,
+	[NE_GCC_USB31_SEC_MOCK_UTMI_CLK_SRC] = &ne_gcc_usb31_sec_mock_utmi_clk_src.clkr,
+	[NE_GCC_USB31_SEC_MOCK_UTMI_POSTDIV_CLK_SRC] =
+		&ne_gcc_usb31_sec_mock_utmi_postdiv_clk_src.clkr,
+	[NE_GCC_USB31_SEC_SLEEP_CLK] = &ne_gcc_usb31_sec_sleep_clk.clkr,
+	[NE_GCC_USB3_PRIM_PHY_AUX_CLK] = &ne_gcc_usb3_prim_phy_aux_clk.clkr,
+	[NE_GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &ne_gcc_usb3_prim_phy_aux_clk_src.clkr,
+	[NE_GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &ne_gcc_usb3_prim_phy_com_aux_clk.clkr,
+	[NE_GCC_USB3_PRIM_PHY_PIPE_CLK] = &ne_gcc_usb3_prim_phy_pipe_clk.clkr,
+	[NE_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &ne_gcc_usb3_prim_phy_pipe_clk_src.clkr,
+	[NE_GCC_USB3_SEC_PHY_AUX_CLK] = &ne_gcc_usb3_sec_phy_aux_clk.clkr,
+	[NE_GCC_USB3_SEC_PHY_AUX_CLK_SRC] = &ne_gcc_usb3_sec_phy_aux_clk_src.clkr,
+	[NE_GCC_USB3_SEC_PHY_COM_AUX_CLK] = &ne_gcc_usb3_sec_phy_com_aux_clk.clkr,
+	[NE_GCC_USB3_SEC_PHY_PIPE_CLK] = &ne_gcc_usb3_sec_phy_pipe_clk.clkr,
+	[NE_GCC_USB3_SEC_PHY_PIPE_CLK_SRC] = &ne_gcc_usb3_sec_phy_pipe_clk_src.clkr,
+};
+
+static struct gdsc *ne_gcc_nord_gdscs[] = {
+	[NE_GCC_UFS_MEM_PHY_GDSC] = &ne_gcc_ufs_mem_phy_gdsc,
+	[NE_GCC_UFS_PHY_GDSC] = &ne_gcc_ufs_phy_gdsc,
+	[NE_GCC_USB20_PRIM_GDSC] = &ne_gcc_usb20_prim_gdsc,
+	[NE_GCC_USB31_PRIM_GDSC] = &ne_gcc_usb31_prim_gdsc,
+	[NE_GCC_USB31_SEC_GDSC] = &ne_gcc_usb31_sec_gdsc,
+	[NE_GCC_USB3_PHY_GDSC] = &ne_gcc_usb3_phy_gdsc,
+	[NE_GCC_USB3_SEC_PHY_GDSC] = &ne_gcc_usb3_sec_phy_gdsc,
+};
+
+static const struct qcom_reset_map ne_gcc_nord_resets[] = {
+	[NE_GCC_GPU_2_BCR] = { 0x34000 },
+	[NE_GCC_QUPV3_WRAPPER_2_BCR] = { 0x38000 },
+	[NE_GCC_SDCC4_BCR] = { 0x18000 },
+	[NE_GCC_UFS_PHY_BCR] = { 0x33000 },
+	[NE_GCC_USB20_PRIM_BCR] = { 0x31000 },
+	[NE_GCC_USB31_PRIM_BCR] = { 0x2a000 },
+	[NE_GCC_USB31_SEC_BCR] = { 0x2c000 },
+	[NE_GCC_USB3_DP_PHY_PRIM_BCR] = { 0x2b008 },
+	[NE_GCC_USB3_DP_PHY_SEC_BCR] = { 0x2d008 },
+	[NE_GCC_USB3_PHY_PRIM_BCR] = { 0x2b000 },
+	[NE_GCC_USB3_PHY_SEC_BCR] = { 0x2d000 },
+	[NE_GCC_USB3PHY_PHY_PRIM_BCR] = { 0x2b004 },
+	[NE_GCC_USB3PHY_PHY_SEC_BCR] = { 0x2d004 },
+};
+
+static const struct clk_rcg_dfs_data ne_gcc_nord_dfs_clocks[] = {
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s0_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s1_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s2_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s3_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s4_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s5_clk_src),
+	DEFINE_RCG_DFS(ne_gcc_qupv3_wrap2_s6_clk_src),
+};
+
+static const struct regmap_config ne_gcc_nord_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xf41f0,
+	.fast_io = true,
+};
+
+static void clk_nord_regs_configure(struct device *dev, struct regmap *regmap)
+{
+	/* FORCE_MEM_CORE_ON for  ne_gcc_ufs_phy_ice_core_clk and ne_gcc_ufs_phy_axi_clk */
+	qcom_branch_set_force_mem_core(regmap, ne_gcc_ufs_phy_ice_core_clk, true);
+	qcom_branch_set_force_mem_core(regmap, ne_gcc_ufs_phy_axi_clk, true);
+}
+
+static struct qcom_cc_driver_data ne_gcc_nord_driver_data = {
+	.dfs_rcgs = ne_gcc_nord_dfs_clocks,
+	.num_dfs_rcgs = ARRAY_SIZE(ne_gcc_nord_dfs_clocks),
+	.clk_regs_configure = clk_nord_regs_configure,
+};
+
+static const struct qcom_cc_desc ne_gcc_nord_desc = {
+	.config = &ne_gcc_nord_regmap_config,
+	.clks = ne_gcc_nord_clocks,
+	.num_clks = ARRAY_SIZE(ne_gcc_nord_clocks),
+	.resets = ne_gcc_nord_resets,
+	.num_resets = ARRAY_SIZE(ne_gcc_nord_resets),
+	.gdscs = ne_gcc_nord_gdscs,
+	.num_gdscs = ARRAY_SIZE(ne_gcc_nord_gdscs),
+	.driver_data = &ne_gcc_nord_driver_data,
+};
+
+static const struct of_device_id ne_gcc_nord_match_table[] = {
+	{ .compatible = "qcom,nord-negcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, ne_gcc_nord_match_table);
+
+static int ne_gcc_nord_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &ne_gcc_nord_desc);
+}
+
+static struct platform_driver ne_gcc_nord_driver = {
+	.probe = ne_gcc_nord_probe,
+	.driver = {
+		.name = "negcc-nord",
+		.of_match_table = ne_gcc_nord_match_table,
+	},
+};
+
+module_platform_driver(ne_gcc_nord_driver);
+
+MODULE_DESCRIPTION("QTI NEGCC NORD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/nwgcc-nord.c b/drivers/clk/qcom/nwgcc-nord.c
new file mode 100644
index 0000000..163ab63
--- /dev/null
+++ b/drivers/clk/qcom/nwgcc-nord.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,nord-nwgcc.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 "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_NW_GCC_GPLL0_OUT_EVEN,
+	P_NW_GCC_GPLL0_OUT_MAIN,
+	P_SLEEP_CLK,
+};
+
+static struct clk_alpha_pll nw_gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_nw_gcc_gpll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv nw_gcc_gpll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_nw_gcc_gpll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_nw_gcc_gpll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "nw_gcc_gpll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&nw_gcc_gpll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static const struct parent_map nw_gcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_NW_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SLEEP_CLK, 5 },
+	{ P_NW_GCC_GPLL0_OUT_EVEN, 6 },
+};
+
+static const struct clk_parent_data nw_gcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &nw_gcc_gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+	{ .hw = &nw_gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_nw_gcc_gp1_clk_src[] = {
+	F(60000000, P_NW_GCC_GPLL0_OUT_MAIN, 10, 0, 0),
+	F(100000000, P_NW_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_NW_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 nw_gcc_gp1_clk_src = {
+	.cmd_rcgr = 0x20004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = nw_gcc_parent_map_0,
+	.freq_tbl = ftbl_nw_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "nw_gcc_gp1_clk_src",
+		.parent_data = nw_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(nw_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 nw_gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x21004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = nw_gcc_parent_map_0,
+	.freq_tbl = ftbl_nw_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "nw_gcc_gp2_clk_src",
+		.parent_data = nw_gcc_parent_data_0,
+		.num_parents = ARRAY_SIZE(nw_gcc_parent_data_0),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_branch nw_gcc_acmu_mux_clk = {
+	.halt_reg = 0x1f01c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1f01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_acmu_mux_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_camera_hf_axi_clk = {
+	.halt_reg = 0x16008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x16008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x16008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_camera_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_camera_sf_axi_clk = {
+	.halt_reg = 0x1601c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1601c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1601c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_camera_sf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_camera_trig_clk = {
+	.halt_reg = 0x16034,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x16034,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x16034,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_camera_trig_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_disp_0_hf_axi_clk = {
+	.halt_reg = 0x18008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x18008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x18008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_disp_0_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_disp_0_trig_clk = {
+	.halt_reg = 0x1801c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1801c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1801c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_disp_0_trig_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_disp_1_hf_axi_clk = {
+	.halt_reg = 0x19008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x19008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x19008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_disp_1_hf_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_disp_1_trig_clk = {
+	.halt_reg = 0x1901c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1901c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1901c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_disp_1_trig_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_dprx0_axi_hf_clk = {
+	.halt_reg = 0x29004,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x29004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x29004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_dprx0_axi_hf_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_dprx1_axi_hf_clk = {
+	.halt_reg = 0x2a004,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x2a004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2a004,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_dprx1_axi_hf_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_eva_axi0_clk = {
+	.halt_reg = 0x1b008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1b008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_eva_axi0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_eva_axi0c_clk = {
+	.halt_reg = 0x1b01c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1b01c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_eva_axi0c_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_eva_trig_clk = {
+	.halt_reg = 0x1b028,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x1b028,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1b028,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_eva_trig_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_frq_measure_ref_clk = {
+	.halt_reg = 0x1f008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1f008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_frq_measure_ref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gp1_clk = {
+	.halt_reg = 0x20000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x20000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gp1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gp2_clk = {
+	.halt_reg = 0x21000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x21000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gp2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gp2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_2_gpll0_clk_src = {
+	.halt_reg = 0x24150,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x24150,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76000,
+		.enable_mask = BIT(6),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_2_gpll0_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gpll0.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_2_gpll0_div_clk_src = {
+	.halt_reg = 0x24158,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x24158,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76000,
+		.enable_mask = BIT(7),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_2_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gpll0_out_even.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_2_hscnoc_gfx_clk = {
+	.halt_reg = 0x2400c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2400c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2400c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_2_hscnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_gpll0_clk_src = {
+	.halt_reg = 0x23150,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23150,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76000,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_gpll0_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gpll0.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_gpll0_div_clk_src = {
+	.halt_reg = 0x23158,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x23158,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x76000,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_gpll0_div_clk_src",
+			.parent_hws = (const struct clk_hw*[]) {
+				&nw_gcc_gpll0_out_even.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_hscnoc_gfx_clk = {
+	.halt_reg = 0x2300c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x2300c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2300c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_hscnoc_gfx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_gpu_smmu_vote_clk = {
+	.halt_reg = 0x86038,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x86038,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_gpu_smmu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_hscnoc_gpu_2_axi_clk = {
+	.halt_reg = 0x24160,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x24160,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x24160,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_hscnoc_gpu_2_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_hscnoc_gpu_axi_clk = {
+	.halt_reg = 0x23160,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x23160,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x23160,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_hscnoc_gpu_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_mmu_1_tcu_vote_clk = {
+	.halt_reg = 0x86040,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x86040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_mmu_1_tcu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_video_axi0_clk = {
+	.halt_reg = 0x1a008,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1a008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1a008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_video_axi0_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_video_axi0c_clk = {
+	.halt_reg = 0x1a01c,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1a01c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1a01c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_video_axi0c_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch nw_gcc_video_axi1_clk = {
+	.halt_reg = 0x1a030,
+	.halt_check = BRANCH_HALT_SKIP,
+	.hwcg_reg = 0x1a030,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x1a030,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "nw_gcc_video_axi1_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_regmap *nw_gcc_nord_clocks[] = {
+	[NW_GCC_ACMU_MUX_CLK] = &nw_gcc_acmu_mux_clk.clkr,
+	[NW_GCC_CAMERA_HF_AXI_CLK] = &nw_gcc_camera_hf_axi_clk.clkr,
+	[NW_GCC_CAMERA_SF_AXI_CLK] = &nw_gcc_camera_sf_axi_clk.clkr,
+	[NW_GCC_CAMERA_TRIG_CLK] = &nw_gcc_camera_trig_clk.clkr,
+	[NW_GCC_DISP_0_HF_AXI_CLK] = &nw_gcc_disp_0_hf_axi_clk.clkr,
+	[NW_GCC_DISP_0_TRIG_CLK] = &nw_gcc_disp_0_trig_clk.clkr,
+	[NW_GCC_DISP_1_HF_AXI_CLK] = &nw_gcc_disp_1_hf_axi_clk.clkr,
+	[NW_GCC_DISP_1_TRIG_CLK] = &nw_gcc_disp_1_trig_clk.clkr,
+	[NW_GCC_DPRX0_AXI_HF_CLK] = &nw_gcc_dprx0_axi_hf_clk.clkr,
+	[NW_GCC_DPRX1_AXI_HF_CLK] = &nw_gcc_dprx1_axi_hf_clk.clkr,
+	[NW_GCC_EVA_AXI0_CLK] = &nw_gcc_eva_axi0_clk.clkr,
+	[NW_GCC_EVA_AXI0C_CLK] = &nw_gcc_eva_axi0c_clk.clkr,
+	[NW_GCC_EVA_TRIG_CLK] = &nw_gcc_eva_trig_clk.clkr,
+	[NW_GCC_FRQ_MEASURE_REF_CLK] = &nw_gcc_frq_measure_ref_clk.clkr,
+	[NW_GCC_GP1_CLK] = &nw_gcc_gp1_clk.clkr,
+	[NW_GCC_GP1_CLK_SRC] = &nw_gcc_gp1_clk_src.clkr,
+	[NW_GCC_GP2_CLK] = &nw_gcc_gp2_clk.clkr,
+	[NW_GCC_GP2_CLK_SRC] = &nw_gcc_gp2_clk_src.clkr,
+	[NW_GCC_GPLL0] = &nw_gcc_gpll0.clkr,
+	[NW_GCC_GPLL0_OUT_EVEN] = &nw_gcc_gpll0_out_even.clkr,
+	[NW_GCC_GPU_2_GPLL0_CLK_SRC] = &nw_gcc_gpu_2_gpll0_clk_src.clkr,
+	[NW_GCC_GPU_2_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_2_gpll0_div_clk_src.clkr,
+	[NW_GCC_GPU_2_HSCNOC_GFX_CLK] = &nw_gcc_gpu_2_hscnoc_gfx_clk.clkr,
+	[NW_GCC_GPU_GPLL0_CLK_SRC] = &nw_gcc_gpu_gpll0_clk_src.clkr,
+	[NW_GCC_GPU_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_gpll0_div_clk_src.clkr,
+	[NW_GCC_GPU_HSCNOC_GFX_CLK] = &nw_gcc_gpu_hscnoc_gfx_clk.clkr,
+	[NW_GCC_GPU_SMMU_VOTE_CLK] = &nw_gcc_gpu_smmu_vote_clk.clkr,
+	[NW_GCC_HSCNOC_GPU_2_AXI_CLK] = &nw_gcc_hscnoc_gpu_2_axi_clk.clkr,
+	[NW_GCC_HSCNOC_GPU_AXI_CLK] = &nw_gcc_hscnoc_gpu_axi_clk.clkr,
+	[NW_GCC_MMU_1_TCU_VOTE_CLK] = &nw_gcc_mmu_1_tcu_vote_clk.clkr,
+	[NW_GCC_VIDEO_AXI0_CLK] = &nw_gcc_video_axi0_clk.clkr,
+	[NW_GCC_VIDEO_AXI0C_CLK] = &nw_gcc_video_axi0c_clk.clkr,
+	[NW_GCC_VIDEO_AXI1_CLK] = &nw_gcc_video_axi1_clk.clkr,
+};
+
+static const struct qcom_reset_map nw_gcc_nord_resets[] = {
+	[NW_GCC_CAMERA_BCR] = { 0x16000 },
+	[NW_GCC_DISPLAY_0_BCR] = { 0x18000 },
+	[NW_GCC_DISPLAY_1_BCR] = { 0x19000 },
+	[NW_GCC_DPRX0_BCR] = { 0x29000 },
+	[NW_GCC_DPRX1_BCR] = { 0x2a000 },
+	[NW_GCC_EVA_BCR] = { 0x1b000 },
+	[NW_GCC_GPU_2_BCR] = { 0x24000 },
+	[NW_GCC_GPU_BCR] = { 0x23000 },
+	[NW_GCC_VIDEO_BCR] = { 0x1a000 },
+};
+
+static u32 nw_gcc_nord_critical_cbcrs[] = {
+	0x16004, /* NW_GCC_CAMERA_AHB_CLK */
+	0x16030, /* NW_GCC_CAMERA_XO_CLK */
+	0x18004, /* NW_GCC_DISP_0_AHB_CLK */
+	0x19004, /* NW_GCC_DISP_1_AHB_CLK */
+	0x29018, /* NW_GCC_DPRX0_CFG_AHB_CLK */
+	0x2a018, /* NW_GCC_DPRX1_CFG_AHB_CLK */
+	0x1b004, /* NW_GCC_EVA_AHB_CLK */
+	0x1b024, /* NW_GCC_EVA_XO_CLK */
+	0x23004, /* NW_GCC_GPU_CFG_AHB_CLK */
+	0x24004, /* NW_GCC_GPU_2_CFG_AHB_CLK */
+	0x1a004, /* NW_GCC_VIDEO_AHB_CLK */
+	0x1a044, /* NW_GCC_VIDEO_XO_CLK */
+};
+
+static struct qcom_cc_driver_data nw_gcc_nord_driver_data = {
+	.clk_cbcrs = nw_gcc_nord_critical_cbcrs,
+	.num_clk_cbcrs = ARRAY_SIZE(nw_gcc_nord_critical_cbcrs),
+};
+
+static const struct regmap_config nw_gcc_nord_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = 0xf41f0,
+	.fast_io = true,
+};
+
+static const struct qcom_cc_desc nw_gcc_nord_desc = {
+	.config = &nw_gcc_nord_regmap_config,
+	.clks = nw_gcc_nord_clocks,
+	.num_clks = ARRAY_SIZE(nw_gcc_nord_clocks),
+	.resets = nw_gcc_nord_resets,
+	.num_resets = ARRAY_SIZE(nw_gcc_nord_resets),
+	.driver_data = &nw_gcc_nord_driver_data,
+};
+
+static const struct of_device_id nw_gcc_nord_match_table[] = {
+	{ .compatible = "qcom,nord-nwgcc" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, nw_gcc_nord_match_table);
+
+static int nw_gcc_nord_probe(struct platform_device *pdev)
+{
+	return qcom_cc_probe(pdev, &nw_gcc_nord_desc);
+}
+
+static struct platform_driver nw_gcc_nord_driver = {
+	.probe = nw_gcc_nord_probe,
+	.driver = {
+		.name = "nwgcc-nord",
+		.of_match_table = nw_gcc_nord_match_table,
+	},
+};
+
+module_platform_driver(nw_gcc_nord_driver);
+
+MODULE_DESCRIPTION("QTI NWGCC NORD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/clk/qcom/segcc-nord.c b/drivers/clk/qcom/segcc-nord.c
new file mode 100644
index 0000000..1aab099
--- /dev/null
+++ b/drivers/clk/qcom/segcc-nord.c
@@ -0,0 +1,1609 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#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,nord-segcc.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 "common.h"
+#include "gdsc.h"
+#include "reset.h"
+
+enum {
+	DT_BI_TCXO,
+	DT_SLEEP_CLK,
+};
+
+enum {
+	P_BI_TCXO,
+	P_SE_GCC_GPLL0_OUT_EVEN,
+	P_SE_GCC_GPLL0_OUT_MAIN,
+	P_SE_GCC_GPLL2_OUT_MAIN,
+	P_SE_GCC_GPLL4_OUT_MAIN,
+	P_SE_GCC_GPLL5_OUT_MAIN,
+	P_SLEEP_CLK,
+};
+
+static struct clk_alpha_pll se_gcc_gpll0 = {
+	.offset = 0x0,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gpll0",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct clk_div_table post_div_table_se_gcc_gpll0_out_even[] = {
+	{ 0x1, 2 },
+	{ }
+};
+
+static struct clk_alpha_pll_postdiv se_gcc_gpll0_out_even = {
+	.offset = 0x0,
+	.post_div_shift = 10,
+	.post_div_table = post_div_table_se_gcc_gpll0_out_even,
+	.num_post_div = ARRAY_SIZE(post_div_table_se_gcc_gpll0_out_even),
+	.width = 4,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_gpll0_out_even",
+		.parent_hws = (const struct clk_hw*[]) {
+			&se_gcc_gpll0.clkr.hw,
+		},
+		.num_parents = 1,
+		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
+	},
+};
+
+static struct clk_alpha_pll se_gcc_gpll2 = {
+	.offset = 0x2000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(2),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gpll2",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll se_gcc_gpll4 = {
+	.offset = 0x4000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(4),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gpll4",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static struct clk_alpha_pll se_gcc_gpll5 = {
+	.offset = 0x5000,
+	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
+	.clkr = {
+		.enable_reg = 0x0,
+		.enable_mask = BIT(5),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gpll5",
+			.parent_data = &(const struct clk_parent_data) {
+				.index = DT_BI_TCXO,
+			},
+			.num_parents = 1,
+			.ops = &clk_alpha_pll_fixed_lucid_ole_ops,
+		},
+	},
+};
+
+static const struct parent_map se_gcc_parent_map_0[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SE_GCC_GPLL0_OUT_EVEN, 2 },
+};
+
+static const struct clk_parent_data se_gcc_parent_data_0[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &se_gcc_gpll0.clkr.hw },
+	{ .hw = &se_gcc_gpll0_out_even.clkr.hw },
+};
+
+static const struct parent_map se_gcc_parent_map_1[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SE_GCC_GPLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data se_gcc_parent_data_1[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &se_gcc_gpll0.clkr.hw },
+};
+
+static const struct parent_map se_gcc_parent_map_2[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data se_gcc_parent_data_2[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &se_gcc_gpll0.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct parent_map se_gcc_parent_map_3[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SE_GCC_GPLL5_OUT_MAIN, 3 },
+	{ P_SE_GCC_GPLL4_OUT_MAIN, 5 },
+	{ P_SE_GCC_GPLL2_OUT_MAIN, 6 },
+};
+
+static const struct clk_parent_data se_gcc_parent_data_3[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &se_gcc_gpll0.clkr.hw },
+	{ .hw = &se_gcc_gpll5.clkr.hw },
+	{ .hw = &se_gcc_gpll4.clkr.hw },
+	{ .hw = &se_gcc_gpll2.clkr.hw },
+};
+
+static const struct parent_map se_gcc_parent_map_4[] = {
+	{ P_BI_TCXO, 0 },
+	{ P_SE_GCC_GPLL0_OUT_MAIN, 1 },
+	{ P_SE_GCC_GPLL0_OUT_EVEN, 2 },
+	{ P_SLEEP_CLK, 5 },
+};
+
+static const struct clk_parent_data se_gcc_parent_data_4[] = {
+	{ .index = DT_BI_TCXO },
+	{ .hw = &se_gcc_gpll0.clkr.hw },
+	{ .hw = &se_gcc_gpll0_out_even.clkr.hw },
+	{ .index = DT_SLEEP_CLK },
+};
+
+static const struct freq_tbl ftbl_se_gcc_eee_emac0_clk_src[] = {
+	F(66666667, P_SE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(100000000, P_SE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 se_gcc_eee_emac0_clk_src = {
+	.cmd_rcgr = 0x240b8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_2,
+	.freq_tbl = ftbl_se_gcc_eee_emac0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_eee_emac0_clk_src",
+		.parent_data = se_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 se_gcc_eee_emac1_clk_src = {
+	.cmd_rcgr = 0x250b8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_2,
+	.freq_tbl = ftbl_se_gcc_eee_emac0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_eee_emac1_clk_src",
+		.parent_data = se_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_se_gcc_emac0_phy_aux_clk_src[] = {
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 se_gcc_emac0_phy_aux_clk_src = {
+	.cmd_rcgr = 0x24030,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_2,
+	.freq_tbl = ftbl_se_gcc_emac0_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac0_phy_aux_clk_src",
+		.parent_data = se_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_se_gcc_emac0_ptp_clk_src[] = {
+	F(150000000, P_SE_GCC_GPLL0_OUT_MAIN, 4, 0, 0),
+	F(250000000, P_SE_GCC_GPLL5_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 se_gcc_emac0_ptp_clk_src = {
+	.cmd_rcgr = 0x24084,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_3,
+	.freq_tbl = ftbl_se_gcc_emac0_ptp_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac0_ptp_clk_src",
+		.parent_data = se_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_se_gcc_emac0_rgmii_clk_src[] = {
+	F(75000000, P_SE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(120000000, P_SE_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	F(250000000, P_SE_GCC_GPLL5_OUT_MAIN, 4, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 se_gcc_emac0_rgmii_clk_src = {
+	.cmd_rcgr = 0x2406c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_3,
+	.freq_tbl = ftbl_se_gcc_emac0_rgmii_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac0_rgmii_clk_src",
+		.parent_data = se_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 se_gcc_emac1_phy_aux_clk_src = {
+	.cmd_rcgr = 0x25030,
+	.mnd_width = 0,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_2,
+	.freq_tbl = ftbl_se_gcc_emac0_phy_aux_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac1_phy_aux_clk_src",
+		.parent_data = se_gcc_parent_data_2,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_2),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 se_gcc_emac1_ptp_clk_src = {
+	.cmd_rcgr = 0x25084,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_3,
+	.freq_tbl = ftbl_se_gcc_emac0_ptp_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac1_ptp_clk_src",
+		.parent_data = se_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 se_gcc_emac1_rgmii_clk_src = {
+	.cmd_rcgr = 0x2506c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_3,
+	.freq_tbl = ftbl_se_gcc_emac0_rgmii_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_emac1_rgmii_clk_src",
+		.parent_data = se_gcc_parent_data_3,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_3),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_se_gcc_gp1_clk_src[] = {
+	F(66666667, P_SE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(100000000, P_SE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(200000000, P_SE_GCC_GPLL0_OUT_MAIN, 3, 0, 0),
+	{ }
+};
+
+static struct clk_rcg2 se_gcc_gp1_clk_src = {
+	.cmd_rcgr = 0x19004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_4,
+	.freq_tbl = ftbl_se_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_gp1_clk_src",
+		.parent_data = se_gcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static struct clk_rcg2 se_gcc_gp2_clk_src = {
+	.cmd_rcgr = 0x1a004,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_4,
+	.freq_tbl = ftbl_se_gcc_gp1_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &(const struct clk_init_data) {
+		.name = "se_gcc_gp2_clk_src",
+		.parent_data = se_gcc_parent_data_4,
+		.num_parents = ARRAY_SIZE(se_gcc_parent_data_4),
+		.flags = CLK_SET_RATE_PARENT,
+		.ops = &clk_rcg2_shared_ops,
+	},
+};
+
+static const struct freq_tbl ftbl_se_gcc_qupv3_wrap0_s0_clk_src[] = {
+	F(7372800, P_SE_GCC_GPLL0_OUT_MAIN, 1, 192, 15625),
+	F(14745600, P_SE_GCC_GPLL0_OUT_MAIN, 1, 384, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_SE_GCC_GPLL0_OUT_MAIN, 1, 768, 15625),
+	F(32000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 4, 75),
+	F(48000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 2, 25),
+	F(51200000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 32, 375),
+	F(64000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 8, 75),
+	F(66666667, P_SE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(75000000, P_SE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(80000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 2, 15),
+	F(96000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 4, 25),
+	F(100000000, P_SE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	F(102400000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 64, 375),
+	F(112000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 14, 75),
+	F(117964800, P_SE_GCC_GPLL0_OUT_MAIN, 1, 3072, 15625),
+	F(120000000, P_SE_GCC_GPLL0_OUT_MAIN, 5, 0, 0),
+	{ }
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s0_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s0_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s0_clk_src = {
+	.cmd_rcgr = 0x2616c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s0_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s1_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s1_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s1_clk_src = {
+	.cmd_rcgr = 0x262a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s1_clk_src_init,
+};
+
+static const struct freq_tbl ftbl_se_gcc_qupv3_wrap0_s2_clk_src[] = {
+	F(7372800, P_SE_GCC_GPLL0_OUT_MAIN, 1, 192, 15625),
+	F(14745600, P_SE_GCC_GPLL0_OUT_MAIN, 1, 384, 15625),
+	F(19200000, P_BI_TCXO, 1, 0, 0),
+	F(29491200, P_SE_GCC_GPLL0_OUT_MAIN, 1, 768, 15625),
+	F(32000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 4, 75),
+	F(48000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 2, 25),
+	F(51200000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 32, 375),
+	F(64000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 8, 75),
+	F(66666667, P_SE_GCC_GPLL0_OUT_MAIN, 9, 0, 0),
+	F(75000000, P_SE_GCC_GPLL0_OUT_MAIN, 8, 0, 0),
+	F(80000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 2, 15),
+	F(96000000, P_SE_GCC_GPLL0_OUT_MAIN, 1, 4, 25),
+	F(100000000, P_SE_GCC_GPLL0_OUT_MAIN, 6, 0, 0),
+	{ }
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s2_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s2_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s2_clk_src = {
+	.cmd_rcgr = 0x263e4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s2_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s3_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s3_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s3_clk_src = {
+	.cmd_rcgr = 0x26520,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s3_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s4_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s4_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s4_clk_src = {
+	.cmd_rcgr = 0x2665c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s4_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s5_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s5_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s5_clk_src = {
+	.cmd_rcgr = 0x26798,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s5_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap0_s6_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap0_s6_clk_src",
+	.parent_data = se_gcc_parent_data_1,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_1),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap0_s6_clk_src = {
+	.cmd_rcgr = 0x268d4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_1,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap0_s6_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s0_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s0_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s0_clk_src = {
+	.cmd_rcgr = 0x2716c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s0_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s1_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s1_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s1_clk_src = {
+	.cmd_rcgr = 0x272a8,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s0_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s1_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s2_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s2_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s2_clk_src = {
+	.cmd_rcgr = 0x273e4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s2_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s3_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s3_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s3_clk_src = {
+	.cmd_rcgr = 0x27520,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s3_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s4_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s4_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s4_clk_src = {
+	.cmd_rcgr = 0x2765c,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s4_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s5_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s5_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s5_clk_src = {
+	.cmd_rcgr = 0x27798,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s5_clk_src_init,
+};
+
+static struct clk_init_data se_gcc_qupv3_wrap1_s6_clk_src_init = {
+	.name = "se_gcc_qupv3_wrap1_s6_clk_src",
+	.parent_data = se_gcc_parent_data_0,
+	.num_parents = ARRAY_SIZE(se_gcc_parent_data_0),
+	.flags = CLK_SET_RATE_PARENT,
+	.ops = &clk_rcg2_shared_no_init_park_ops,
+};
+
+static struct clk_rcg2 se_gcc_qupv3_wrap1_s6_clk_src = {
+	.cmd_rcgr = 0x278d4,
+	.mnd_width = 16,
+	.hid_width = 5,
+	.parent_map = se_gcc_parent_map_0,
+	.freq_tbl = ftbl_se_gcc_qupv3_wrap0_s2_clk_src,
+	.hw_clk_ctrl = true,
+	.clkr.hw.init = &se_gcc_qupv3_wrap1_s6_clk_src_init,
+};
+
+static struct clk_branch se_gcc_eee_emac0_clk = {
+	.halt_reg = 0x240b4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x240b4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_eee_emac0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_eee_emac0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_eee_emac1_clk = {
+	.halt_reg = 0x250b4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x250b4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_eee_emac1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_eee_emac1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_axi_clk = {
+	.halt_reg = 0x2401c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2401c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2401c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_cc_sgmiiphy_rx_clk = {
+	.halt_reg = 0x24064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x24064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_cc_sgmiiphy_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_cc_sgmiiphy_tx_clk = {
+	.halt_reg = 0x2405c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2405c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_cc_sgmiiphy_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_phy_aux_clk = {
+	.halt_reg = 0x2402c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2402c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac0_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_ptp_clk = {
+	.halt_reg = 0x24048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x24048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_ptp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac0_ptp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_rgmii_clk = {
+	.halt_reg = 0x24058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x24058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_rgmii_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac0_rgmii_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_rpcs_rx_clk = {
+	.halt_reg = 0x240a8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x240a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_rpcs_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_rpcs_tx_clk = {
+	.halt_reg = 0x240a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x240a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_rpcs_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_xgxs_rx_clk = {
+	.halt_reg = 0x240b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x240b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_xgxs_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac0_xgxs_tx_clk = {
+	.halt_reg = 0x240ac,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x240ac,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac0_xgxs_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_axi_clk = {
+	.halt_reg = 0x2501c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x2501c,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x2501c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_axi_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_cc_sgmiiphy_rx_clk = {
+	.halt_reg = 0x25064,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x25064,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_cc_sgmiiphy_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_cc_sgmiiphy_tx_clk = {
+	.halt_reg = 0x2505c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2505c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_cc_sgmiiphy_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_phy_aux_clk = {
+	.halt_reg = 0x2502c,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x2502c,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_phy_aux_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac1_phy_aux_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_ptp_clk = {
+	.halt_reg = 0x25048,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x25048,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_ptp_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac1_ptp_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_rgmii_clk = {
+	.halt_reg = 0x25058,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x25058,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_rgmii_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_emac1_rgmii_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_rpcs_rx_clk = {
+	.halt_reg = 0x250a8,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x250a8,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_rpcs_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_rpcs_tx_clk = {
+	.halt_reg = 0x250a4,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x250a4,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_rpcs_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_xgxs_rx_clk = {
+	.halt_reg = 0x250b0,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x250b0,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_xgxs_rx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_emac1_xgxs_tx_clk = {
+	.halt_reg = 0x250ac,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x250ac,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_emac1_xgxs_tx_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_frq_measure_ref_clk = {
+	.halt_reg = 0x18008,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x18008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_frq_measure_ref_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_gp1_clk = {
+	.halt_reg = 0x19000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x19000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gp1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_gp1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_gp2_clk = {
+	.halt_reg = 0x1a000,
+	.halt_check = BRANCH_HALT,
+	.clkr = {
+		.enable_reg = 0x1a000,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_gp2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_gp2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_mmu_2_tcu_vote_clk = {
+	.halt_reg = 0x57040,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57040,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_mmu_2_tcu_vote_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_core_2x_clk = {
+	.halt_reg = 0x26020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(15),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_core_clk = {
+	.halt_reg = 0x2600c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(14),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_m_ahb_clk = {
+	.halt_reg = 0x26004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x26004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(12),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s0_clk = {
+	.halt_reg = 0x2615c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(16),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s1_clk = {
+	.halt_reg = 0x26298,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(17),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s2_clk = {
+	.halt_reg = 0x263d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(18),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s3_clk = {
+	.halt_reg = 0x26510,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(19),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s4_clk = {
+	.halt_reg = 0x2664c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(20),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s5_clk = {
+	.halt_reg = 0x26788,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(21),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s6_clk = {
+	.halt_reg = 0x268c4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(22),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap0_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap0_s_ahb_clk = {
+	.halt_reg = 0x26008,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x26008,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(13),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap0_s_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_core_2x_clk = {
+	.halt_reg = 0x27020,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(26),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_core_2x_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_core_clk = {
+	.halt_reg = 0x2700c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(25),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_core_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_m_ahb_clk = {
+	.halt_reg = 0x27004,
+	.halt_check = BRANCH_HALT_VOTED,
+	.hwcg_reg = 0x27004,
+	.hwcg_bit = 1,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(23),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_m_ahb_clk",
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s0_clk = {
+	.halt_reg = 0x2715c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(27),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s0_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s0_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s1_clk = {
+	.halt_reg = 0x27298,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(28),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s1_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s1_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s2_clk = {
+	.halt_reg = 0x273d4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(29),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s2_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s2_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s3_clk = {
+	.halt_reg = 0x27510,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(30),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s3_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s3_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s4_clk = {
+	.halt_reg = 0x2764c,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57000,
+		.enable_mask = BIT(31),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s4_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s4_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s5_clk = {
+	.halt_reg = 0x27788,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(0),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s5_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s5_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+};
+
+static struct clk_branch se_gcc_qupv3_wrap1_s6_clk = {
+	.halt_reg = 0x278c4,
+	.halt_check = BRANCH_HALT_VOTED,
+	.clkr = {
+		.enable_reg = 0x57008,
+		.enable_mask = BIT(1),
+		.hw.init = &(const struct clk_init_data) {
+			.name = "se_gcc_qupv3_wrap1_s6_clk",
+			.parent_hws = (const struct clk_hw*[]) {
+				&se_gcc_qupv3_wrap1_s6_clk_src.clkr.hw,
+			},
+			.num_parents = 1,
+			.flags = CLK_SET_RATE_PARENT,
+			.ops = &clk_branch2_ops,
+		},
+	},
+