From 08f87f769b595151be1afeff53e144f543faa614 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 06 Dec 2023 09:51:13 +0000
Subject: [PATCH] add dts config

---
 kernel/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c | 1749 +++++++++++++++++++++++++++++++++++----------------------
 1 files changed, 1,077 insertions(+), 672 deletions(-)

diff --git a/kernel/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c b/kernel/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c
index 52c040a..12d6cc8 100644
--- a/kernel/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c
+++ b/kernel/drivers/gpu/arm/bifrost/mali_kbase_core_linux.c
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
 /*
  *
- * (C) COPYRIGHT 2010-2021 ARM Limited. All rights reserved.
+ * (C) COPYRIGHT 2010-2023 ARM Limited. All rights reserved.
  *
  * This program is free software and is provided to you under the terms of the
  * GNU General Public License version 2 as published by the Free Software
@@ -31,7 +31,8 @@
 #include <ipa/mali_kbase_ipa_debugfs.h>
 #endif /* CONFIG_DEVFREQ_THERMAL */
 #endif /* CONFIG_MALI_BIFROST_DEVFREQ */
-#include "mali_kbase_mem_profile_debugfs_buf_size.h"
+#include "backend/gpu/mali_kbase_model_linux.h"
+#include "uapi/gpu/arm/bifrost/mali_kbase_mem_profile_debugfs_buf_size.h"
 #include "mali_kbase_mem.h"
 #include "mali_kbase_mem_pool_debugfs.h"
 #include "mali_kbase_mem_pool_group.h"
@@ -50,15 +51,16 @@
 #if !MALI_USE_CSF
 #include "mali_kbase_kinstr_jm.h"
 #endif
-#include "mali_kbase_hwcnt_context.h"
-#include "mali_kbase_hwcnt_virtualizer.h"
-#include "mali_kbase_hwcnt_legacy.h"
+#include "hwcnt/mali_kbase_hwcnt_context.h"
+#include "hwcnt/mali_kbase_hwcnt_virtualizer.h"
+#include "mali_kbase_kinstr_prfcnt.h"
 #include "mali_kbase_vinstr.h"
 #if MALI_USE_CSF
 #include "csf/mali_kbase_csf_firmware.h"
 #include "csf/mali_kbase_csf_tiler_heap.h"
 #include "csf/mali_kbase_csf_csg_debugfs.h"
 #include "csf/mali_kbase_csf_cpu_queue_debugfs.h"
+#include "csf/mali_kbase_csf_event.h"
 #endif
 #ifdef CONFIG_MALI_ARBITER_SUPPORT
 #include "arbiter/mali_kbase_arbiter_pm.h"
@@ -71,6 +73,9 @@
 #endif
 #include "backend/gpu/mali_kbase_pm_internal.h"
 #include "mali_kbase_dvfs_debugfs.h"
+#if IS_ENABLED(CONFIG_DEBUG_FS)
+#include "mali_kbase_pbha_debugfs.h"
+#endif
 
 #include <linux/module.h>
 #include <linux/init.h>
@@ -78,6 +83,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/platform_device.h>
 #include <linux/of_platform.h>
 #include <linux/miscdevice.h>
@@ -86,14 +92,16 @@
 #include <linux/fs.h>
 #include <linux/uaccess.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 #include <linux/mm.h>
 #include <linux/compat.h>	/* is_compat_task/in_compat_syscall */
 #include <linux/mman.h>
 #include <linux/version.h>
+#include <linux/version_compat_defs.h>
 #include <mali_kbase_hw.h>
-#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE)
+#if IS_ENABLED(CONFIG_SYNC_FILE)
 #include <mali_kbase_sync.h>
-#endif /* CONFIG_SYNC || CONFIG_SYNC_FILE */
+#endif /* CONFIG_SYNC_FILE */
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
@@ -113,11 +121,6 @@
 
 #include <mali_kbase_caps.h>
 
-/* GPU IRQ Tags */
-#define	JOB_IRQ_TAG	0
-#define MMU_IRQ_TAG	1
-#define GPU_IRQ_TAG	2
-
 #define KERNEL_SIDE_DDK_VERSION_STRING "K:" MALI_RELEASE_NAME "(GPL)"
 
 /**
@@ -129,16 +132,16 @@
 					 (((minor) & 0xFFF) << 8) | \
 					 ((0 & 0xFF) << 0))
 
-#define KBASE_API_MIN(api_version) ((api_version >> 8) & 0xFFF)
-#define KBASE_API_MAJ(api_version) ((api_version >> 20) & 0xFFF)
-
 /**
- * typedef mali_kbase_capability_def - kbase capabilities table
+ * struct mali_kbase_capability_def - kbase capabilities table
+ *
+ * @required_major: required major
+ * @required_minor: required minor
  */
-typedef struct mali_kbase_capability_def {
+struct mali_kbase_capability_def {
 	u16 required_major;
 	u16 required_minor;
-} mali_kbase_capability_def;
+};
 
 /*
  * This must be kept in-sync with mali_kbase_cap
@@ -146,32 +149,46 @@
  * TODO: The alternative approach would be to embed the cap enum values
  * in the table. Less efficient but potentially safer.
  */
-static mali_kbase_capability_def kbase_caps_table[MALI_KBASE_NUM_CAPS] = {
+static const struct mali_kbase_capability_def kbase_caps_table[MALI_KBASE_NUM_CAPS] = {
 #if MALI_USE_CSF
-	{ 1, 0 },               /* SYSTEM_MONITOR 	*/
-	{ 1, 0 },               /* JIT_PRESSURE_LIMIT	*/
-	{ 1, 0 },               /* MEM_GROW_ON_GPF	*/
-	{ 1, 0 }                /* MEM_PROTECTED	*/
+	{ 1, 0 },               /* SYSTEM_MONITOR */
+	{ 1, 0 },               /* JIT_PRESSURE_LIMIT */
+	{ 1, 0 },               /* MEM_GROW_ON_GPF */
+	{ 1, 0 }                /* MEM_PROTECTED */
 #else
-	{ 11, 15 },             /* SYSTEM_MONITOR 	*/
-	{ 11, 25 },             /* JIT_PRESSURE_LIMIT	*/
-	{ 11,  2 },             /* MEM_GROW_ON_GPF	*/
-	{ 11,  2 }              /* MEM_PROTECTED	*/
+	{ 11, 15 },             /* SYSTEM_MONITOR */
+	{ 11, 25 },             /* JIT_PRESSURE_LIMIT */
+	{ 11,  2 },             /* MEM_GROW_ON_GPF */
+	{ 11,  2 }              /* MEM_PROTECTED */
 #endif
 };
+
+#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
+/* Mutex to synchronize the probe of multiple kbase instances */
+static struct mutex kbase_probe_mutex;
+#endif
+
+#ifndef CONFIG_MALI_BIFROST_DEVFREQ
+static inline int kbase_devfreq_opp_helper(struct dev_pm_set_opp_data *data)
+{
+	return -EOPNOTSUPP;
+}
+#endif
 
 /**
  * mali_kbase_supports_cap - Query whether a kbase capability is supported
  *
- * @api_version: 	API version to convert
- * @cap:		Capability to query for - see mali_kbase_caps.h
+ * @api_version: API version to convert
+ * @cap:         Capability to query for - see mali_kbase_caps.h
+ *
+ * Return: true if the capability is supported
  */
-bool mali_kbase_supports_cap(unsigned long api_version, mali_kbase_cap cap)
+bool mali_kbase_supports_cap(unsigned long api_version, enum mali_kbase_cap cap)
 {
 	bool supported = false;
 	unsigned long required_ver;
 
-	mali_kbase_capability_def const *cap_def;
+	struct mali_kbase_capability_def const *cap_def;
 
 	if (WARN_ON(cap < 0))
 		return false;
@@ -198,7 +215,7 @@
  * address space) and no API version number. Both must be assigned before
  * kbase_file_get_kctx_if_setup_complete() can be used successfully.
  *
- * @return Address of an object representing a simulated device file, or NULL
+ * Return: Address of an object representing a simulated device file, or NULL
  *         on failure.
  */
 static struct kbase_file *kbase_file_new(struct kbase_device *const kbdev,
@@ -297,10 +314,9 @@
  *
  * @kfile: A device file created by kbase_file_new()
  *
- * This function returns an error code (encoded with ERR_PTR) if no context
- * has been created for the given @kfile. This makes it safe to use in
- * circumstances where the order of initialization cannot be enforced, but
- * only if the caller checks the return value.
+ * This function returns NULL if no context has been created for the given @kfile.
+ * This makes it safe to use in circumstances where the order of initialization
+ * cannot be enforced, but only if the caller checks the return value.
  *
  * Return: Address of the kernel base context associated with the @kfile, or
  *         NULL if no context exists.
@@ -339,15 +355,6 @@
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 		kbasep_mem_profile_debugfs_remove(kctx);
 #endif
-
-		mutex_lock(&kctx->legacy_hwcnt_lock);
-		/* If this client was performing hardware counter dumping and
-		 * did not explicitly detach itself, destroy it now
-		 */
-		kbase_hwcnt_legacy_client_destroy(kctx->legacy_hwcnt_cli);
-		kctx->legacy_hwcnt_cli = NULL;
-		mutex_unlock(&kctx->legacy_hwcnt_lock);
-
 		kbase_context_debugfs_term(kctx);
 
 		kbase_destroy_context(kctx);
@@ -404,6 +411,22 @@
 	return -EPERM;
 }
 
+static int kbase_api_kinstr_prfcnt_enum_info(
+	struct kbase_file *kfile,
+	struct kbase_ioctl_kinstr_prfcnt_enum_info *prfcnt_enum_info)
+{
+	return kbase_kinstr_prfcnt_enum_info(kfile->kbdev->kinstr_prfcnt_ctx,
+					     prfcnt_enum_info);
+}
+
+static int kbase_api_kinstr_prfcnt_setup(
+	struct kbase_file *kfile,
+	union kbase_ioctl_kinstr_prfcnt_setup *prfcnt_setup)
+{
+	return kbase_kinstr_prfcnt_setup(kfile->kbdev->kinstr_prfcnt_ctx,
+					 prfcnt_setup);
+}
+
 static struct kbase_device *to_kbase_device(struct device *dev)
 {
 	return dev_get_drvdata(dev);
@@ -411,6 +434,12 @@
 
 int assign_irqs(struct kbase_device *kbdev)
 {
+	static const char *const irq_names_caps[] = { "JOB", "MMU", "GPU" };
+
+#if IS_ENABLED(CONFIG_OF)
+	static const char *const irq_names[] = { "job", "mmu", "gpu" };
+#endif
+
 	struct platform_device *pdev;
 	int i;
 
@@ -418,34 +447,31 @@
 		return -ENODEV;
 
 	pdev = to_platform_device(kbdev->dev);
-	/* 3 IRQ resources */
-	for (i = 0; i < 3; i++) {
-		struct resource *irq_res;
-		int irqtag;
 
-		irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
-		if (!irq_res) {
-			dev_err(kbdev->dev, "No IRQ resource at index %d\n", i);
-			return -ENOENT;
-		}
+	for (i = 0; i < ARRAY_SIZE(irq_names_caps); i++) {
+		int irq;
 
 #if IS_ENABLED(CONFIG_OF)
-		if (!strncasecmp(irq_res->name, "JOB", 4)) {
-			irqtag = JOB_IRQ_TAG;
-		} else if (!strncasecmp(irq_res->name, "MMU", 4)) {
-			irqtag = MMU_IRQ_TAG;
-		} else if (!strncasecmp(irq_res->name, "GPU", 4)) {
-			irqtag = GPU_IRQ_TAG;
-		} else {
-			dev_err(&pdev->dev, "Invalid irq res name: '%s'\n",
-				irq_res->name);
-			return -EINVAL;
-		}
+		/* We recommend using Upper case for the irq names in dts, but if
+		 * there are devices in the world using Lower case then we should
+		 * avoid breaking support for them. So try using names in Upper case
+		 * first then try using Lower case names. If both attempts fail then
+		 * we assume there is no IRQ resource specified for the GPU.
+		 */
+		irq = platform_get_irq_byname(pdev, irq_names_caps[i]);
+		if (irq < 0)
+			irq = platform_get_irq_byname(pdev, irq_names[i]);
 #else
-		irqtag = i;
+		irq = platform_get_irq(pdev, i);
 #endif /* CONFIG_OF */
-		kbdev->irqs[irqtag].irq = irq_res->start;
-		kbdev->irqs[irqtag].flags = irq_res->flags & IRQF_TRIGGER_MASK;
+
+		if (irq < 0) {
+			dev_err(kbdev->dev, "No IRQ resource '%s'\n", irq_names_caps[i]);
+			return irq;
+		}
+
+		kbdev->irqs[i].irq = irq;
+		kbdev->irqs[i].flags = irqd_get_trigger_type(irq_get_irq_data(irq));
 	}
 
 	return 0;
@@ -481,27 +507,6 @@
 EXPORT_SYMBOL(kbase_release_device);
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
-#if KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE &&                            \
-	!(KERNEL_VERSION(4, 4, 28) <= LINUX_VERSION_CODE &&                    \
-	  KERNEL_VERSION(4, 5, 0) > LINUX_VERSION_CODE)
-/*
- * Older versions, before v4.6, of the kernel doesn't have
- * kstrtobool_from_user(), except longterm 4.4.y which had it added in 4.4.28
- */
-static int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
-{
-	char buf[4];
-
-	count = min(count, sizeof(buf) - 1);
-
-	if (copy_from_user(buf, s, count))
-		return -EFAULT;
-	buf[count] = '\0';
-
-	return strtobool(buf, res);
-}
-#endif
-
 static ssize_t write_ctx_infinite_cache(struct file *f, const char __user *ubuf, size_t size, loff_t *off)
 {
 	struct kbase_context *kctx = f->private_data;
@@ -613,13 +618,8 @@
 
 	kbdev = kfile->kbdev;
 
-#if (KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE)
 	kctx = kbase_create_context(kbdev, in_compat_syscall(),
 		flags, kfile->api_version, kfile->filp);
-#else
-	kctx = kbase_create_context(kbdev, is_compat_task(),
-		flags, kfile->api_version, kfile->filp);
-#endif /* (KERNEL_VERSION(4, 6, 0) <= LINUX_VERSION_CODE) */
 
 	/* if bad flags, will stay stuck in setup mode */
 	if (!kctx)
@@ -629,7 +629,8 @@
 		kbase_ctx_flag_set(kctx, KCTX_INFINITE_CACHE);
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
-	snprintf(kctx_name, 64, "%d_%d", kctx->tgid, kctx->id);
+	if (unlikely(!scnprintf(kctx_name, 64, "%d_%d", kctx->tgid, kctx->id)))
+		return -ENOMEM;
 
 	mutex_init(&kctx->mem_profile_lock);
 
@@ -640,16 +641,8 @@
 		/* we don't treat this as a fail - just warn about it */
 		dev_warn(kbdev->dev, "couldn't create debugfs dir for kctx\n");
 	} else {
-#if (KERNEL_VERSION(4, 7, 0) > LINUX_VERSION_CODE)
-		/* prevent unprivileged use of debug file system
-		 * in old kernel version
-		 */
-		debugfs_create_file("infinite_cache", 0600, kctx->kctx_dentry,
-			kctx, &kbase_infinite_cache_fops);
-#else
 		debugfs_create_file("infinite_cache", 0644, kctx->kctx_dentry,
 			kctx, &kbase_infinite_cache_fops);
-#endif
 		debugfs_create_file("force_same_va", 0600, kctx->kctx_dentry,
 			kctx, &kbase_force_same_va_fops);
 
@@ -675,6 +668,11 @@
 
 	if (!kbdev)
 		return -ENODEV;
+
+#if (KERNEL_VERSION(6, 0, 0) > LINUX_VERSION_CODE)
+	/* Set address space operations for page migration */
+	kbase_mem_migrate_set_address_space_ops(kbdev, filp);
+#endif
 
 	/* Device-wide firmware load is moved here from probing to comply with
 	 * Android GKI vendor guideline.
@@ -770,14 +768,14 @@
 }
 #endif /* !MALI_USE_CSF */
 
-static int kbase_api_get_gpuprops(struct kbase_context *kctx,
+static int kbase_api_get_gpuprops(struct kbase_file *kfile,
 		struct kbase_ioctl_get_gpuprops *get_props)
 {
-	struct kbase_gpu_props *kprops = &kctx->kbdev->gpu_props;
+	struct kbase_gpu_props *kprops = &kfile->kbdev->gpu_props;
 	int err;
 
 	if (get_props->flags != 0) {
-		dev_err(kctx->kbdev->dev, "Unsupported flags to get_gpuprops");
+		dev_err(kfile->kbdev->dev, "Unsupported flags to get_gpuprops");
 		return -EINVAL;
 	}
 
@@ -802,23 +800,134 @@
 }
 #endif /* !MALI_USE_CSF */
 
-static int kbase_api_mem_alloc(struct kbase_context *kctx,
-		union kbase_ioctl_mem_alloc *alloc)
+#if MALI_USE_CSF
+static int kbase_api_mem_alloc_ex(struct kbase_context *kctx,
+				  union kbase_ioctl_mem_alloc_ex *alloc_ex)
+{
+	struct kbase_va_region *reg;
+	u64 flags = alloc_ex->in.flags;
+	u64 gpu_va;
+
+	/* Calls to this function are inherently asynchronous, with respect to
+	 * MMU operations.
+	 */
+	const enum kbase_caller_mmu_sync_info mmu_sync_info = CALLER_MMU_ASYNC;
+
+	bool gpu_executable = (flags & BASE_MEM_PROT_GPU_EX) && kbase_has_exec_va_zone(kctx);
+	bool fixed_or_fixable = (flags & (BASE_MEM_FIXED | BASE_MEM_FIXABLE));
+
+	if (!kbase_mem_allow_alloc(kctx))
+		return -EINVAL;
+
+	/* The driver counts the number of FIXABLE and FIXED allocations because
+	 * they're not supposed to happen at the same time. However, that is not
+	 * a security concern: nothing bad happens if the two types of allocations
+	 * are made at the same time. The only reason why the driver is guarding
+	 * against them is because there's no client use case that is supposed
+	 * to need both of them at the same time, and the driver wants to help
+	 * the user space catch some obvious mistake.
+	 *
+	 * The driver is able to switch from FIXABLE allocations to FIXED and
+	 * vice versa, if all the allocations of one kind are freed before trying
+	 * to create allocations of a different kind.
+	 */
+	if ((flags & BASE_MEM_FIXED) && (atomic64_read(&kctx->num_fixable_allocs) > 0))
+		return -EINVAL;
+
+	if ((flags & BASE_MEM_FIXABLE) && (atomic64_read(&kctx->num_fixed_allocs) > 0))
+		return -EINVAL;
+
+	if (flags & BASEP_MEM_FLAGS_KERNEL_ONLY)
+		return -ENOMEM;
+
+	/* The fixed_address parameter must be either a non-zero, page-aligned
+	 * value for FIXED allocations or zero for any other kind of allocation.
+	 */
+	if (flags & BASE_MEM_FIXED) {
+		u64 aligned_fixed_address = alloc_ex->in.fixed_address & PAGE_MASK;
+
+		if ((aligned_fixed_address == 0) ||
+		    (aligned_fixed_address != alloc_ex->in.fixed_address))
+			return -EINVAL;
+
+		gpu_va = aligned_fixed_address;
+	} else if (alloc_ex->in.fixed_address != 0) {
+		return -EINVAL;
+	}
+
+	/* For 64-bit clients, force SAME_VA up to 2^(47)-1.
+	 * For 32-bit clients, force SAME_VA up to 2^(32)-1.
+	 *
+	 * In both cases, the executable and fixed/fixable zones, and
+	 * the executable+fixed/fixable zone, are all above this range.
+	 */
+	if ((!kbase_ctx_flag(kctx, KCTX_COMPAT)) &&
+			kbase_ctx_flag(kctx, KCTX_FORCE_SAME_VA)) {
+		if (!gpu_executable && !fixed_or_fixable)
+			flags |= BASE_MEM_SAME_VA;
+	}
+
+	/* If CSF event memory allocation, need to force certain flags.
+	 * SAME_VA - GPU address needs to be used as a CPU address, explicit
+	 * mmap has to be avoided.
+	 * CACHED_CPU - Frequent access to the event memory by CPU.
+	 * COHERENT_SYSTEM - No explicit cache maintenance around the access
+	 * to event memory so need to leverage the coherency support.
+	 */
+	if (flags & BASE_MEM_CSF_EVENT) {
+		/* We cannot honor this request */
+		if (gpu_executable || fixed_or_fixable)
+			return -ENOMEM;
+
+		flags |= (BASE_MEM_SAME_VA |
+			  BASE_MEM_CACHED_CPU |
+			  BASE_MEM_COHERENT_SYSTEM);
+	}
+
+	reg = kbase_mem_alloc(kctx, alloc_ex->in.va_pages, alloc_ex->in.commit_pages,
+			      alloc_ex->in.extension, &flags, &gpu_va, mmu_sync_info);
+
+	if (!reg)
+		return -ENOMEM;
+
+	alloc_ex->out.flags = flags;
+	alloc_ex->out.gpu_va = gpu_va;
+
+	return 0;
+}
+
+static int kbase_api_mem_alloc(struct kbase_context *kctx, union kbase_ioctl_mem_alloc *alloc)
+{
+	int ret;
+	union kbase_ioctl_mem_alloc_ex mem_alloc_ex = { { 0 } };
+
+	mem_alloc_ex.in.va_pages = alloc->in.va_pages;
+	mem_alloc_ex.in.commit_pages = alloc->in.commit_pages;
+	mem_alloc_ex.in.extension = alloc->in.extension;
+	mem_alloc_ex.in.flags = alloc->in.flags;
+	mem_alloc_ex.in.fixed_address = 0;
+
+	ret = kbase_api_mem_alloc_ex(kctx, &mem_alloc_ex);
+
+	alloc->out.flags = mem_alloc_ex.out.flags;
+	alloc->out.gpu_va = mem_alloc_ex.out.gpu_va;
+
+	return ret;
+}
+#else
+static int kbase_api_mem_alloc(struct kbase_context *kctx, union kbase_ioctl_mem_alloc *alloc)
 {
 	struct kbase_va_region *reg;
 	u64 flags = alloc->in.flags;
 	u64 gpu_va;
 
-	rcu_read_lock();
-	/* Don't allow memory allocation until user space has set up the
-	 * tracking page (which sets kctx->process_mm). Also catches when we've
-	 * forked.
+	/* Calls to this function are inherently asynchronous, with respect to
+	 * MMU operations.
 	 */
-	if (rcu_dereference(kctx->process_mm) != current->mm) {
-		rcu_read_unlock();
+	const enum kbase_caller_mmu_sync_info mmu_sync_info = CALLER_MMU_ASYNC;
+
+	if (!kbase_mem_allow_alloc(kctx))
 		return -EINVAL;
-	}
-	rcu_read_unlock();
 
 	if (flags & BASEP_MEM_FLAGS_KERNEL_ONLY)
 		return -ENOMEM;
@@ -828,29 +937,13 @@
 	 * has been initialized. In that case, GPU-executable memory may
 	 * or may not be SAME_VA.
 	 */
-	if ((!kbase_ctx_flag(kctx, KCTX_COMPAT)) &&
-			kbase_ctx_flag(kctx, KCTX_FORCE_SAME_VA)) {
+	if ((!kbase_ctx_flag(kctx, KCTX_COMPAT)) && kbase_ctx_flag(kctx, KCTX_FORCE_SAME_VA)) {
 		if (!(flags & BASE_MEM_PROT_GPU_EX) || !kbase_has_exec_va_zone(kctx))
 			flags |= BASE_MEM_SAME_VA;
 	}
 
-#if MALI_USE_CSF
-	/* If CSF event memory allocation, need to force certain flags.
-	 * SAME_VA - GPU address needs to be used as a CPU address, explicit
-	 * mmap has to be avoided.
-	 * CACHED_CPU - Frequent access to the event memory by CPU.
-	 * COHERENT_SYSTEM - No explicit cache maintenance around the access
-	 * to event memory so need to leverage the coherency support.
-	 */
-	if (flags & BASE_MEM_CSF_EVENT) {
-		flags |= (BASE_MEM_SAME_VA |
-			  BASE_MEM_CACHED_CPU |
-			  BASE_MEM_COHERENT_SYSTEM);
-	}
-#endif
-
-	reg = kbase_mem_alloc(kctx, alloc->in.va_pages, alloc->in.commit_pages,
-			      alloc->in.extension, &flags, &gpu_va);
+	reg = kbase_mem_alloc(kctx, alloc->in.va_pages, alloc->in.commit_pages, alloc->in.extension,
+			      &flags, &gpu_va, mmu_sync_info);
 
 	if (!reg)
 		return -ENOMEM;
@@ -860,6 +953,7 @@
 
 	return 0;
 }
+#endif /* MALI_USE_CSF */
 
 static int kbase_api_mem_query(struct kbase_context *kctx,
 		union kbase_ioctl_mem_query *query)
@@ -888,69 +982,13 @@
 	return kbase_vinstr_hwcnt_reader_setup(kctx->kbdev->vinstr_ctx, setup);
 }
 
-static int kbase_api_hwcnt_enable(struct kbase_context *kctx,
-		struct kbase_ioctl_hwcnt_enable *enable)
-{
-	int ret;
-
-	mutex_lock(&kctx->legacy_hwcnt_lock);
-	if (enable->dump_buffer != 0) {
-		/* Non-zero dump buffer, so user wants to create the client */
-		if (kctx->legacy_hwcnt_cli == NULL) {
-			ret = kbase_hwcnt_legacy_client_create(
-				kctx->kbdev->hwcnt_gpu_virt,
-				enable,
-				&kctx->legacy_hwcnt_cli);
-		} else {
-			/* This context already has a client */
-			ret = -EBUSY;
-		}
-	} else {
-		/* Zero dump buffer, so user wants to destroy the client */
-		if (kctx->legacy_hwcnt_cli != NULL) {
-			kbase_hwcnt_legacy_client_destroy(
-				kctx->legacy_hwcnt_cli);
-			kctx->legacy_hwcnt_cli = NULL;
-			ret = 0;
-		} else {
-			/* This context has no client to destroy */
-			ret = -EINVAL;
-		}
-	}
-	mutex_unlock(&kctx->legacy_hwcnt_lock);
-
-	return ret;
-}
-
-static int kbase_api_hwcnt_dump(struct kbase_context *kctx)
-{
-	int ret;
-
-	mutex_lock(&kctx->legacy_hwcnt_lock);
-	ret = kbase_hwcnt_legacy_client_dump(kctx->legacy_hwcnt_cli);
-	mutex_unlock(&kctx->legacy_hwcnt_lock);
-
-	return ret;
-}
-
-static int kbase_api_hwcnt_clear(struct kbase_context *kctx)
-{
-	int ret;
-
-	mutex_lock(&kctx->legacy_hwcnt_lock);
-	ret = kbase_hwcnt_legacy_client_clear(kctx->legacy_hwcnt_cli);
-	mutex_unlock(&kctx->legacy_hwcnt_lock);
-
-	return ret;
-}
-
 static int kbase_api_get_cpu_gpu_timeinfo(struct kbase_context *kctx,
 		union kbase_ioctl_get_cpu_gpu_timeinfo *timeinfo)
 {
 	u32 flags = timeinfo->in.request_flags;
-	struct timespec64 ts;
-	u64 timestamp;
-	u64 cycle_cnt;
+	struct timespec64 ts = { 0 };
+	u64 timestamp = 0;
+	u64 cycle_cnt = 0;
 
 	kbase_pm_context_active(kctx->kbdev);
 
@@ -975,6 +1013,13 @@
 	return 0;
 }
 
+#if IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
+static int kbase_api_hwcnt_set(struct kbase_context *kctx,
+		struct kbase_ioctl_hwcnt_values *values)
+{
+	return gpu_model_set_dummy_prfcnt_user_sample(u64_to_user_ptr(values->data), values->size);
+}
+#endif /* CONFIG_MALI_BIFROST_NO_MALI */
 
 static int kbase_api_disjoint_query(struct kbase_context *kctx,
 		struct kbase_ioctl_disjoint_query *query)
@@ -1006,51 +1051,10 @@
 	return len;
 }
 
-/* Defaults for legacy just-in-time memory allocator initialization
- * kernel calls
- */
-#define DEFAULT_MAX_JIT_ALLOCATIONS 255
-#define JIT_LEGACY_TRIM_LEVEL (0) /* No trimming */
-
-static int kbase_api_mem_jit_init_10_2(struct kbase_context *kctx,
-		struct kbase_ioctl_mem_jit_init_10_2 *jit_init)
-{
-	kctx->jit_version = 1;
-
-	/* since no phys_pages parameter, use the maximum: va_pages */
-	return kbase_region_tracker_init_jit(kctx, jit_init->va_pages,
-			DEFAULT_MAX_JIT_ALLOCATIONS,
-			JIT_LEGACY_TRIM_LEVEL, BASE_MEM_GROUP_DEFAULT,
-			jit_init->va_pages);
-}
-
-static int kbase_api_mem_jit_init_11_5(struct kbase_context *kctx,
-		struct kbase_ioctl_mem_jit_init_11_5 *jit_init)
-{
-	int i;
-
-	kctx->jit_version = 2;
-
-	for (i = 0; i < sizeof(jit_init->padding); i++) {
-		/* Ensure all padding bytes are 0 for potential future
-		 * extension
-		 */
-		if (jit_init->padding[i])
-			return -EINVAL;
-	}
-
-	/* since no phys_pages parameter, use the maximum: va_pages */
-	return kbase_region_tracker_init_jit(kctx, jit_init->va_pages,
-			jit_init->max_allocations, jit_init->trim_level,
-			jit_init->group_id, jit_init->va_pages);
-}
-
 static int kbase_api_mem_jit_init(struct kbase_context *kctx,
 		struct kbase_ioctl_mem_jit_init *jit_init)
 {
 	int i;
-
-	kctx->jit_version = 3;
 
 	for (i = 0; i < sizeof(jit_init->padding); i++) {
 		/* Ensure all padding bytes are 0 for potential future
@@ -1209,7 +1213,7 @@
 static int kbase_api_stream_create(struct kbase_context *kctx,
 		struct kbase_ioctl_stream_create *stream)
 {
-#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE)
+#if IS_ENABLED(CONFIG_SYNC_FILE)
 	int fd, ret;
 
 	/* Name must be NULL-terminated and padded with NULLs, so check last
@@ -1231,7 +1235,7 @@
 static int kbase_api_fence_validate(struct kbase_context *kctx,
 		struct kbase_ioctl_fence_validate *validate)
 {
-#if defined(CONFIG_SYNC) || defined(CONFIG_SYNC_FILE)
+#if IS_ENABLED(CONFIG_SYNC_FILE)
 	return kbase_sync_fence_validate(validate->fd);
 #else
 	return -ENOENT;
@@ -1245,12 +1249,18 @@
 	int err;
 
 	if (data->len > KBASE_MEM_PROFILE_MAX_BUF_SIZE) {
-		dev_err(kctx->kbdev->dev, "mem_profile_add: buffer too big\n");
+		dev_err(kctx->kbdev->dev, "mem_profile_add: buffer too big");
 		return -EINVAL;
 	}
 
+	if (!data->len) {
+		dev_err(kctx->kbdev->dev, "mem_profile_add: buffer size is 0");
+		/* Should return -EINVAL, but returning -ENOMEM for backwards compat */
+		return -ENOMEM;
+	}
+
 	buf = kmalloc(data->len, GFP_KERNEL);
-	if (ZERO_OR_NULL_PTR(buf))
+	if (!buf)
 		return -ENOMEM;
 
 	err = copy_from_user(buf, u64_to_user_ptr(data->buffer),
@@ -1398,6 +1408,30 @@
 	return kbase_csf_queue_kick(kctx, kick);
 }
 
+static int kbasep_cs_queue_group_create_1_6(
+	struct kbase_context *kctx,
+	union kbase_ioctl_cs_queue_group_create_1_6 *create)
+{
+	union kbase_ioctl_cs_queue_group_create
+		new_create = { .in = {
+				       .tiler_mask = create->in.tiler_mask,
+				       .fragment_mask =
+					       create->in.fragment_mask,
+				       .compute_mask = create->in.compute_mask,
+				       .cs_min = create->in.cs_min,
+				       .priority = create->in.priority,
+				       .tiler_max = create->in.tiler_max,
+				       .fragment_max = create->in.fragment_max,
+				       .compute_max = create->in.compute_max,
+			       } };
+
+	int ret = kbase_csf_queue_group_create(kctx, &new_create);
+
+	create->out.group_handle = new_create.out.group_handle;
+	create->out.group_uid = new_create.out.group_uid;
+
+	return ret;
+}
 static int kbasep_cs_queue_group_create(struct kbase_context *kctx,
 			     union kbase_ioctl_cs_queue_group_create *create)
 {
@@ -1433,12 +1467,31 @@
 static int kbasep_cs_tiler_heap_init(struct kbase_context *kctx,
 		union kbase_ioctl_cs_tiler_heap_init *heap_init)
 {
+	if (heap_init->in.group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS)
+		return -EINVAL;
+
 	kctx->jit_group_id = heap_init->in.group_id;
 
 	return kbase_csf_tiler_heap_init(kctx, heap_init->in.chunk_size,
-		heap_init->in.initial_chunks, heap_init->in.max_chunks,
-		heap_init->in.target_in_flight,
-		&heap_init->out.gpu_heap_va, &heap_init->out.first_chunk_va);
+					 heap_init->in.initial_chunks, heap_init->in.max_chunks,
+					 heap_init->in.target_in_flight, heap_init->in.buf_desc_va,
+					 &heap_init->out.gpu_heap_va,
+					 &heap_init->out.first_chunk_va);
+}
+
+static int kbasep_cs_tiler_heap_init_1_13(struct kbase_context *kctx,
+					  union kbase_ioctl_cs_tiler_heap_init_1_13 *heap_init)
+{
+	if (heap_init->in.group_id >= MEMORY_GROUP_MANAGER_NR_GROUPS)
+		return -EINVAL;
+
+	kctx->jit_group_id = heap_init->in.group_id;
+
+	return kbase_csf_tiler_heap_init(kctx, heap_init->in.chunk_size,
+					 heap_init->in.initial_chunks, heap_init->in.max_chunks,
+					 heap_init->in.target_in_flight, 0,
+					 &heap_init->out.gpu_heap_va,
+					 &heap_init->out.first_chunk_va);
 }
 
 static int kbasep_cs_tiler_heap_term(struct kbase_context *kctx,
@@ -1520,6 +1573,30 @@
 					cpu_queue_info->size);
 }
 
+static int kbase_ioctl_read_user_page(struct kbase_context *kctx,
+				      union kbase_ioctl_read_user_page *user_page)
+{
+	struct kbase_device *kbdev = kctx->kbdev;
+	unsigned long flags;
+
+	/* As of now, only LATEST_FLUSH is supported */
+	if (unlikely(user_page->in.offset != LATEST_FLUSH))
+		return -EINVAL;
+
+	/* Validating padding that must be zero */
+	if (unlikely(user_page->in.padding != 0))
+		return -EINVAL;
+
+	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);
+	if (!kbdev->pm.backend.gpu_powered)
+		user_page->out.val_lo = POWER_DOWN_LATEST_FLUSH_VALUE;
+	else
+		user_page->out.val_lo = kbase_reg_read(kbdev, USER_REG(LATEST_FLUSH));
+	user_page->out.val_hi = 0;
+	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
+
+	return 0;
+}
 #endif /* MALI_USE_CSF */
 
 static int kbasep_ioctl_context_priority_check(struct kbase_context *kctx,
@@ -1644,6 +1721,24 @@
 				struct kbase_ioctl_set_flags,
 				kfile);
 		break;
+
+	case KBASE_IOCTL_KINSTR_PRFCNT_ENUM_INFO:
+		KBASE_HANDLE_IOCTL_INOUT(
+			KBASE_IOCTL_KINSTR_PRFCNT_ENUM_INFO,
+			kbase_api_kinstr_prfcnt_enum_info,
+			struct kbase_ioctl_kinstr_prfcnt_enum_info, kfile);
+		break;
+
+	case KBASE_IOCTL_KINSTR_PRFCNT_SETUP:
+		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_KINSTR_PRFCNT_SETUP,
+					 kbase_api_kinstr_prfcnt_setup,
+					 union kbase_ioctl_kinstr_prfcnt_setup,
+					 kfile);
+		break;
+	case KBASE_IOCTL_GET_GPUPROPS:
+		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_GET_GPUPROPS, kbase_api_get_gpuprops,
+				      struct kbase_ioctl_get_gpuprops, kfile);
+		break;
 	}
 
 	kctx = kbase_file_get_kctx_if_setup_complete(kfile);
@@ -1660,12 +1755,6 @@
 				kctx);
 		break;
 #endif /* !MALI_USE_CSF */
-	case KBASE_IOCTL_GET_GPUPROPS:
-		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_GET_GPUPROPS,
-				kbase_api_get_gpuprops,
-				struct kbase_ioctl_get_gpuprops,
-				kctx);
-		break;
 #if !MALI_USE_CSF
 	case KBASE_IOCTL_POST_TERM:
 		KBASE_HANDLE_IOCTL(KBASE_IOCTL_POST_TERM,
@@ -1679,6 +1768,12 @@
 				union kbase_ioctl_mem_alloc,
 				kctx);
 		break;
+#if MALI_USE_CSF
+	case KBASE_IOCTL_MEM_ALLOC_EX:
+		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_MEM_ALLOC_EX, kbase_api_mem_alloc_ex,
+					 union kbase_ioctl_mem_alloc_ex, kctx);
+		break;
+#endif
 	case KBASE_IOCTL_MEM_QUERY:
 		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_MEM_QUERY,
 				kbase_api_mem_query,
@@ -1701,18 +1796,6 @@
 		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_GET_DDK_VERSION,
 				kbase_api_get_ddk_version,
 				struct kbase_ioctl_get_ddk_version,
-				kctx);
-		break;
-	case KBASE_IOCTL_MEM_JIT_INIT_10_2:
-		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_MEM_JIT_INIT_10_2,
-				kbase_api_mem_jit_init_10_2,
-				struct kbase_ioctl_mem_jit_init_10_2,
-				kctx);
-		break;
-	case KBASE_IOCTL_MEM_JIT_INIT_11_5:
-		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_MEM_JIT_INIT_11_5,
-				kbase_api_mem_jit_init_11_5,
-				struct kbase_ioctl_mem_jit_init_11_5,
 				kctx);
 		break;
 	case KBASE_IOCTL_MEM_JIT_INIT:
@@ -1842,28 +1925,20 @@
 				struct kbase_ioctl_hwcnt_reader_setup,
 				kctx);
 		break;
-	case KBASE_IOCTL_HWCNT_ENABLE:
-		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_HWCNT_ENABLE,
-				kbase_api_hwcnt_enable,
-				struct kbase_ioctl_hwcnt_enable,
-				kctx);
-		break;
-	case KBASE_IOCTL_HWCNT_DUMP:
-		KBASE_HANDLE_IOCTL(KBASE_IOCTL_HWCNT_DUMP,
-				kbase_api_hwcnt_dump,
-				kctx);
-		break;
-	case KBASE_IOCTL_HWCNT_CLEAR:
-		KBASE_HANDLE_IOCTL(KBASE_IOCTL_HWCNT_CLEAR,
-				kbase_api_hwcnt_clear,
-				kctx);
-		break;
 	case KBASE_IOCTL_GET_CPU_GPU_TIMEINFO:
 		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_GET_CPU_GPU_TIMEINFO,
 				kbase_api_get_cpu_gpu_timeinfo,
 				union kbase_ioctl_get_cpu_gpu_timeinfo,
 				kctx);
 		break;
+#if IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
+	case KBASE_IOCTL_HWCNT_SET:
+		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_HWCNT_SET,
+				kbase_api_hwcnt_set,
+				struct kbase_ioctl_hwcnt_values,
+				kctx);
+		break;
+#endif /* CONFIG_MALI_BIFROST_NO_MALI */
 #ifdef CONFIG_MALI_CINSTR_GWT
 	case KBASE_IOCTL_CINSTR_GWT_START:
 		KBASE_HANDLE_IOCTL(KBASE_IOCTL_CINSTR_GWT_START,
@@ -1918,6 +1993,12 @@
 				struct kbase_ioctl_cs_queue_kick,
 				kctx);
 		break;
+	case KBASE_IOCTL_CS_QUEUE_GROUP_CREATE_1_6:
+		KBASE_HANDLE_IOCTL_INOUT(
+			KBASE_IOCTL_CS_QUEUE_GROUP_CREATE_1_6,
+			kbasep_cs_queue_group_create_1_6,
+			union kbase_ioctl_cs_queue_group_create_1_6, kctx);
+		break;
 	case KBASE_IOCTL_CS_QUEUE_GROUP_CREATE:
 		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_CS_QUEUE_GROUP_CREATE,
 				kbasep_cs_queue_group_create,
@@ -1954,6 +2035,11 @@
 				union kbase_ioctl_cs_tiler_heap_init,
 				kctx);
 		break;
+	case KBASE_IOCTL_CS_TILER_HEAP_INIT_1_13:
+		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_CS_TILER_HEAP_INIT_1_13,
+					 kbasep_cs_tiler_heap_init_1_13,
+					 union kbase_ioctl_cs_tiler_heap_init_1_13, kctx);
+		break;
 	case KBASE_IOCTL_CS_TILER_HEAP_TERM:
 		KBASE_HANDLE_IOCTL_IN(KBASE_IOCTL_CS_TILER_HEAP_TERM,
 				kbasep_cs_tiler_heap_term,
@@ -1971,6 +2057,11 @@
 				kbasep_ioctl_cs_cpu_queue_dump,
 				struct kbase_ioctl_cs_cpu_queue_info,
 				kctx);
+		break;
+	/* This IOCTL will be kept for backward compatibility */
+	case KBASE_IOCTL_READ_USER_PAGE:
+		KBASE_HANDLE_IOCTL_INOUT(KBASE_IOCTL_READ_USER_PAGE, kbase_ioctl_read_user_page,
+					 union kbase_ioctl_read_user_page, kctx);
 		break;
 #endif /* MALI_USE_CSF */
 #if MALI_UNIT_TEST
@@ -2014,10 +2105,13 @@
 	if (unlikely(!kctx))
 		return -EPERM;
 
+	if (count < data_size)
+		return -ENOBUFS;
+
 	if (atomic_read(&kctx->event_count))
 		read_event = true;
 	else
-		read_error = kbase_csf_read_error(kctx, &event_data);
+		read_error = kbase_csf_event_read_error(kctx, &event_data);
 
 	if (!read_event && !read_error) {
 		bool dump = kbase_csf_cpu_queue_read_dump_req(kctx,
@@ -2059,6 +2153,8 @@
 	if (count < sizeof(uevent))
 		return -ENOBUFS;
 
+	memset(&uevent, 0, sizeof(uevent));
+
 	do {
 		while (kbase_event_dequeue(kctx, &uevent)) {
 			if (out_count > 0)
@@ -2090,18 +2186,28 @@
 }
 #endif /* MALI_USE_CSF */
 
-static unsigned int kbase_poll(struct file *filp, poll_table *wait)
+static __poll_t kbase_poll(struct file *filp, poll_table *wait)
 {
 	struct kbase_file *const kfile = filp->private_data;
 	struct kbase_context *const kctx =
 		kbase_file_get_kctx_if_setup_complete(kfile);
 
-	if (unlikely(!kctx))
+	if (unlikely(!kctx)) {
+#if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE)
 		return POLLERR;
+#else
+		return EPOLLERR;
+#endif
+	}
 
 	poll_wait(filp, &kctx->event_queue, wait);
-	if (kbase_event_pending(kctx))
+	if (kbase_event_pending(kctx)) {
+#if (KERNEL_VERSION(4, 19, 0) > LINUX_VERSION_CODE)
 		return POLLIN | POLLRDNORM;
+#else
+		return EPOLLIN | EPOLLRDNORM;
+#endif
+	}
 
 	return 0;
 }
@@ -2119,16 +2225,22 @@
 #if MALI_USE_CSF
 int kbase_event_pending(struct kbase_context *ctx)
 {
-	WARN_ON_ONCE(!ctx);
+	KBASE_DEBUG_ASSERT(ctx);
+
+	if (unlikely(!ctx))
+		return -EPERM;
 
 	return (atomic_read(&ctx->event_count) != 0) ||
-		kbase_csf_error_pending(ctx) ||
+		kbase_csf_event_error_pending(ctx) ||
 		kbase_csf_cpu_queue_dump_needed(ctx);
 }
 #else
 int kbase_event_pending(struct kbase_context *ctx)
 {
 	KBASE_DEBUG_ASSERT(ctx);
+
+	if (unlikely(!ctx))
+		return -EPERM;
 
 	return (atomic_read(&ctx->event_count) != 0) ||
 		(atomic_read(&ctx->event_closed) != 0);
@@ -2188,19 +2300,19 @@
 };
 
 /**
- * show_policy - Show callback for the power_policy sysfs file.
- *
- * This function is called to get the contents of the power_policy sysfs
- * file. This is a list of the available policies with the currently active one
- * surrounded by square brackets.
+ * power_policy_show - Show callback for the power_policy sysfs file.
  *
  * @dev:	The device this sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The output buffer for the sysfs file contents
  *
+ * This function is called to get the contents of the power_policy sysfs
+ * file. This is a list of the available policies with the currently active one
+ * surrounded by square brackets.
+ *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_policy(struct device *dev, struct device_attribute *attr, char *const buf)
+static ssize_t power_policy_show(struct device *dev, struct device_attribute *attr, char *const buf)
 {
 	struct kbase_device *kbdev;
 	const struct kbase_pm_policy *current_policy;
@@ -2237,21 +2349,21 @@
 }
 
 /**
- * set_policy - Store callback for the power_policy sysfs file.
- *
- * This function is called when the power_policy sysfs file is written to.
- * It matches the requested policy against the available policies and if a
- * matching policy is found calls kbase_pm_set_policy() to change the
- * policy.
+ * power_policy_store - Store callback for the power_policy sysfs file.
  *
  * @dev:	The device with sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The value written to the sysfs file
  * @count:	The number of bytes to write to the sysfs file
  *
+ * This function is called when the power_policy sysfs file is written to.
+ * It matches the requested policy against the available policies and if a
+ * matching policy is found calls kbase_pm_set_policy() to change the
+ * policy.
+ *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_policy(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t power_policy_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
 	const struct kbase_pm_policy *new_policy = NULL;
@@ -2290,20 +2402,20 @@
  * determining which policy is currently active, and changing the active
  * policy.
  */
-static DEVICE_ATTR(power_policy, S_IRUGO | S_IWUSR, show_policy, set_policy);
+static DEVICE_ATTR_RW(power_policy);
 
 /*
- * show_core_mask - Show callback for the core_mask sysfs file.
- *
- * This function is called to get the contents of the core_mask sysfs file.
+ * core_mask_show - Show callback for the core_mask sysfs file.
  *
  * @dev:	The device this sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The output buffer for the sysfs file contents
  *
+ * This function is called to get the contents of the core_mask sysfs file.
+ *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_core_mask(struct device *dev, struct device_attribute *attr, char * const buf)
+static ssize_t core_mask_show(struct device *dev, struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
 	unsigned long flags;
@@ -2348,18 +2460,18 @@
 }
 
 /**
- * set_core_mask - Store callback for the core_mask sysfs file.
- *
- * This function is called when the core_mask sysfs file is written to.
+ * core_mask_store - Store callback for the core_mask sysfs file.
  *
  * @dev:	The device with sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The value written to the sysfs file
  * @count:	The number of bytes to write to the sysfs file
  *
+ * This function is called when the core_mask sysfs file is written to.
+ *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_core_mask(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t core_mask_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
 #if MALI_USE_CSF
@@ -2489,11 +2601,11 @@
  * Reading it will show the current core mask and the mask of cores available.
  * Writing to it will set the current core mask.
  */
-static DEVICE_ATTR(core_mask, S_IRUGO | S_IWUSR, show_core_mask, set_core_mask);
+static DEVICE_ATTR_RW(core_mask);
 
 #if !MALI_USE_CSF
 /**
- * set_soft_job_timeout - Store callback for the soft_job_timeout sysfs
+ * soft_job_timeout_store - Store callback for the soft_job_timeout sysfs
  * file.
  *
  * @dev: The device this sysfs file is for.
@@ -2509,7 +2621,7 @@
  *
  * Return: count if the function succeeded. An error code on failure.
  */
-static ssize_t set_soft_job_timeout(struct device *dev,
+static ssize_t soft_job_timeout_store(struct device *dev,
 				      struct device_attribute *attr,
 				      const char *buf, size_t count)
 {
@@ -2531,18 +2643,18 @@
 }
 
 /**
- * show_soft_job_timeout - Show callback for the soft_job_timeout sysfs
+ * soft_job_timeout_show - Show callback for the soft_job_timeout sysfs
  * file.
- *
- * This will return the timeout for the software jobs.
  *
  * @dev: The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf: The output buffer for the sysfs file contents.
  *
+ * This will return the timeout for the software jobs.
+ *
  * Return: The number of bytes output to buf.
  */
-static ssize_t show_soft_job_timeout(struct device *dev,
+static ssize_t soft_job_timeout_show(struct device *dev,
 				       struct device_attribute *attr,
 				       char * const buf)
 {
@@ -2556,14 +2668,14 @@
 			 atomic_read(&kbdev->js_data.soft_job_timeout_ms));
 }
 
-static DEVICE_ATTR(soft_job_timeout, S_IRUGO | S_IWUSR,
-		   show_soft_job_timeout, set_soft_job_timeout);
+static DEVICE_ATTR_RW(soft_job_timeout);
 
 static u32 timeout_ms_to_ticks(struct kbase_device *kbdev, long timeout_ms,
 				int default_ticks, u32 old_ticks)
 {
 	if (timeout_ms > 0) {
 		u64 ticks = timeout_ms * 1000000ULL;
+
 		do_div(ticks, kbdev->js_data.scheduling_period_ns);
 		if (!ticks)
 			return 1;
@@ -2576,7 +2688,12 @@
 }
 
 /**
- * set_js_timeouts - Store callback for the js_timeouts sysfs file.
+ * js_timeouts_store - Store callback for the js_timeouts sysfs file.
+ *
+ * @dev:	The device with sysfs file is for
+ * @attr:	The attributes of the sysfs file
+ * @buf:	The value written to the sysfs file
+ * @count:	The number of bytes to write to the sysfs file
  *
  * This function is called to get the contents of the js_timeouts sysfs
  * file. This file contains five values separated by whitespace. The values
@@ -2589,14 +2706,9 @@
  * use by the job scheduler to get override. Note that a value needs to
  * be other than 0 for it to override the current job scheduler value.
  *
- * @dev:	The device with sysfs file is for
- * @attr:	The attributes of the sysfs file
- * @buf:	The value written to the sysfs file
- * @count:	The number of bytes to write to the sysfs file
- *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_js_timeouts(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t js_timeouts_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
 	int items;
@@ -2676,19 +2788,20 @@
 }
 
 /**
- * show_js_timeouts - Show callback for the js_timeouts sysfs file.
+ * js_timeouts_show - Show callback for the js_timeouts sysfs file.
+ *
+ * @dev:	The device this sysfs file is for
+ * @attr:	The attributes of the sysfs file
+ * @buf:	The output buffer for the sysfs file contents
  *
  * This function is called to get the contents of the js_timeouts sysfs
  * file. It returns the last set values written to the js_timeouts sysfs file.
  * If the file didn't get written yet, the values will be current setting in
  * use.
- * @dev:	The device this sysfs file is for
- * @attr:	The attributes of the sysfs file
- * @buf:	The output buffer for the sysfs file contents
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_js_timeouts(struct device *dev, struct device_attribute *attr, char * const buf)
+static ssize_t js_timeouts_show(struct device *dev, struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
 	ssize_t ret;
@@ -2751,7 +2864,7 @@
  * JS_RESET_TICKS_CL
  * JS_RESET_TICKS_DUMPING.
  */
-static DEVICE_ATTR(js_timeouts, S_IRUGO | S_IWUSR, show_js_timeouts, set_js_timeouts);
+static DEVICE_ATTR_RW(js_timeouts);
 
 static u32 get_new_js_timeout(
 		u32 old_period,
@@ -2759,12 +2872,13 @@
 		u32 new_scheduling_period_ns)
 {
 	u64 ticks = (u64)old_period * (u64)old_ticks;
+
 	do_div(ticks, new_scheduling_period_ns);
 	return ticks?ticks:1;
 }
 
 /**
- * set_js_scheduling_period - Store callback for the js_scheduling_period sysfs
+ * js_scheduling_period_store - Store callback for the js_scheduling_period sysfs
  *                            file
  * @dev:   The device the sysfs file is for
  * @attr:  The attributes of the sysfs file
@@ -2777,7 +2891,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_js_scheduling_period(struct device *dev,
+static ssize_t js_scheduling_period_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
@@ -2846,7 +2960,7 @@
 }
 
 /**
- * show_js_scheduling_period - Show callback for the js_scheduling_period sysfs
+ * js_scheduling_period_show - Show callback for the js_scheduling_period sysfs
  *                             entry.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
@@ -2857,7 +2971,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_js_scheduling_period(struct device *dev,
+static ssize_t js_scheduling_period_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -2876,12 +2990,11 @@
 	return ret;
 }
 
-static DEVICE_ATTR(js_scheduling_period, S_IRUGO | S_IWUSR,
-		show_js_scheduling_period, set_js_scheduling_period);
+static DEVICE_ATTR_RW(js_scheduling_period);
 
 
 #ifdef CONFIG_MALI_BIFROST_DEBUG
-static ssize_t set_js_softstop_always(struct device *dev,
+static ssize_t js_softstop_always_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
@@ -2906,7 +3019,7 @@
 	return count;
 }
 
-static ssize_t show_js_softstop_always(struct device *dev,
+static ssize_t js_softstop_always_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -2933,7 +3046,7 @@
  * used for debug and unit-testing purposes.
  * (see CL t6xx_stress_1 unit-test as an example whereby this feature is used.)
  */
-static DEVICE_ATTR(js_softstop_always, S_IRUGO | S_IWUSR, show_js_softstop_always, set_js_softstop_always);
+static DEVICE_ATTR_RW(js_softstop_always);
 #endif /* CONFIG_MALI_BIFROST_DEBUG */
 #endif /* !MALI_USE_CSF */
 
@@ -2952,7 +3065,7 @@
 	kbasep_debug_command_func *func;
 };
 
-void kbasep_ktrace_dump_wrapper(struct kbase_device *kbdev)
+static void kbasep_ktrace_dump_wrapper(struct kbase_device *kbdev)
 {
 	KBASE_KTRACE_DUMP(kbdev);
 }
@@ -2960,24 +3073,24 @@
 /* Debug commands supported by the driver */
 static const struct kbasep_debug_command debug_commands[] = {
 	{
-	 .str = "dumptrace",
-	 .func = &kbasep_ktrace_dump_wrapper,
-	 }
+		.str = "dumptrace",
+		.func = &kbasep_ktrace_dump_wrapper,
+	}
 };
 
 /**
- * show_debug - Show callback for the debug_command sysfs file.
- *
- * This function is called to get the contents of the debug_command sysfs
- * file. This is a list of the available debug commands, separated by newlines.
+ * debug_command_show - Show callback for the debug_command sysfs file.
  *
  * @dev:	The device this sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The output buffer for the sysfs file contents
  *
+ * This function is called to get the contents of the debug_command sysfs
+ * file. This is a list of the available debug commands, separated by newlines.
+ *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_debug(struct device *dev, struct device_attribute *attr, char * const buf)
+static ssize_t debug_command_show(struct device *dev, struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
 	int i;
@@ -3001,21 +3114,21 @@
 }
 
 /**
- * issue_debug - Store callback for the debug_command sysfs file.
- *
- * This function is called when the debug_command sysfs file is written to.
- * It matches the requested command against the available commands, and if
- * a matching command is found calls the associated function from
- * @debug_commands to issue the command.
+ * debug_command_store - Store callback for the debug_command sysfs file.
  *
  * @dev:	The device with sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The value written to the sysfs file
  * @count:	The number of bytes written to the sysfs file
  *
+ * This function is called when the debug_command sysfs file is written to.
+ * It matches the requested command against the available commands, and if
+ * a matching command is found calls the associated function from
+ * @debug_commands to issue the command.
+ *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t issue_debug(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t debug_command_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
 	int i;
@@ -3043,11 +3156,11 @@
  * Reading it will produce a list of debug commands, separated by newlines.
  * Writing to it with one of those commands will issue said command.
  */
-static DEVICE_ATTR(debug_command, S_IRUGO | S_IWUSR, show_debug, issue_debug);
+static DEVICE_ATTR_RW(debug_command);
 #endif /* CONFIG_MALI_BIFROST_DEBUG */
 
 /**
- * kbase_show_gpuinfo - Show callback for the gpuinfo sysfs entry.
+ * gpuinfo_show - Show callback for the gpuinfo sysfs entry.
  * @dev: The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf: The output buffer to receive the GPU information.
@@ -3061,57 +3174,63 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t kbase_show_gpuinfo(struct device *dev,
+static ssize_t gpuinfo_show(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 {
 	static const struct gpu_product_id_name {
-		unsigned id;
+		unsigned int id;
 		char *name;
 	} gpu_product_id_names[] = {
-		{ .id = GPU_ID2_PRODUCT_TMIX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TMIX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G71" },
-		{ .id = GPU_ID2_PRODUCT_THEX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_THEX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G72" },
-		{ .id = GPU_ID2_PRODUCT_TSIX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TSIX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G51" },
-		{ .id = GPU_ID2_PRODUCT_TNOX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TNOX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G76" },
-		{ .id = GPU_ID2_PRODUCT_TDVX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TDVX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G31" },
-		{ .id = GPU_ID2_PRODUCT_TGOX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TGOX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G52" },
-		{ .id = GPU_ID2_PRODUCT_TTRX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TTRX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G77" },
-		{ .id = GPU_ID2_PRODUCT_TBEX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TBEX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G78" },
-		{ .id = GPU_ID2_PRODUCT_TBAX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TBAX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G78AE" },
-		{ .id = GPU_ID2_PRODUCT_LBEX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_LBEX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G68" },
-		{ .id = GPU_ID2_PRODUCT_TNAX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TNAX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G57" },
-		{ .id = GPU_ID2_PRODUCT_TODX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TODX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G710" },
-		{ .id = GPU_ID2_PRODUCT_LODX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_LODX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G610" },
-		{ .id = GPU_ID2_PRODUCT_TGRX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TGRX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G510" },
-		{ .id = GPU_ID2_PRODUCT_TVAX >> GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		{ .id = GPU_ID2_PRODUCT_TVAX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
 		  .name = "Mali-G310" },
+		{ .id = GPU_ID2_PRODUCT_TTIX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		  .name = "Mali-TTIX" },
+		{ .id = GPU_ID2_PRODUCT_LTIX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT,
+		  .name = "Mali-LTIX" },
 	};
 	const char *product_name = "(Unknown Mali GPU)";
 	struct kbase_device *kbdev;
 	u32 gpu_id;
-	unsigned product_id, product_id_mask;
-	unsigned i;
+	unsigned int product_id, product_id_mask;
+	unsigned int i;
+	struct kbase_gpu_props *gpu_props;
 
 	kbdev = to_kbase_device(dev);
 	if (!kbdev)
 		return -ENODEV;
 
-	gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
-	product_id = gpu_id >> GPU_ID_VERSION_PRODUCT_ID_SHIFT;
-	product_id_mask = GPU_ID2_PRODUCT_MODEL >> GPU_ID_VERSION_PRODUCT_ID_SHIFT;
+	gpu_props = &kbdev->gpu_props;
+	gpu_id = gpu_props->props.raw_props.gpu_id;
+	product_id = gpu_id >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT;
+	product_id_mask = GPU_ID2_PRODUCT_MODEL >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT;
 
 	for (i = 0; i < ARRAY_SIZE(gpu_product_id_names); ++i) {
 		const struct gpu_product_id_name *p = &gpu_product_id_names[i];
@@ -3123,16 +3242,42 @@
 		}
 	}
 
-	return scnprintf(buf, PAGE_SIZE, "%s %d cores r%dp%d 0x%04X\n",
-		product_name, kbdev->gpu_props.num_cores,
-		(gpu_id & GPU_ID_VERSION_MAJOR) >> GPU_ID_VERSION_MAJOR_SHIFT,
-		(gpu_id & GPU_ID_VERSION_MINOR) >> GPU_ID_VERSION_MINOR_SHIFT,
-		product_id);
+#if MALI_USE_CSF
+	if ((product_id & product_id_mask) ==
+	    ((GPU_ID2_PRODUCT_TTUX >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT) & product_id_mask)) {
+		const bool rt_supported =
+			GPU_FEATURES_RAY_TRACING_GET(gpu_props->props.raw_props.gpu_features);
+		const u8 nr_cores = gpu_props->num_cores;
+
+		/* Mali-G715-Immortalis if 10 < number of cores with ray tracing supproted.
+		 * Mali-G715 if 10 < number of cores without ray tracing supported.
+		 * Mali-G715 if 7 <= number of cores <= 10 regardless ray tracing.
+		 * Mali-G615 if number of cores < 7.
+		 */
+		if ((nr_cores > 10) && rt_supported)
+			product_name = "Mali-G715-Immortalis";
+		else if (nr_cores >= 7)
+			product_name = "Mali-G715";
+
+		if (nr_cores < 7) {
+			dev_warn(kbdev->dev, "nr_cores(%u) GPU ID must be G615", nr_cores);
+			product_name = "Mali-G615";
+		} else
+			dev_dbg(kbdev->dev, "GPU ID_Name: %s, nr_cores(%u)\n", product_name,
+				nr_cores);
+	}
+#endif /* MALI_USE_CSF */
+
+	return scnprintf(buf, PAGE_SIZE, "%s %d cores r%dp%d 0x%04X\n", product_name,
+			 kbdev->gpu_props.num_cores,
+			 (gpu_id & GPU_ID_VERSION_MAJOR) >> KBASE_GPU_ID_VERSION_MAJOR_SHIFT,
+			 (gpu_id & GPU_ID_VERSION_MINOR) >> KBASE_GPU_ID_VERSION_MINOR_SHIFT,
+			 product_id);
 }
-static DEVICE_ATTR(gpuinfo, S_IRUGO, kbase_show_gpuinfo, NULL);
+static DEVICE_ATTR_RO(gpuinfo);
 
 /**
- * set_dvfs_period - Store callback for the dvfs_period sysfs file.
+ * dvfs_period_store - Store callback for the dvfs_period sysfs file.
  * @dev:   The device with sysfs file is for
  * @attr:  The attributes of the sysfs file
  * @buf:   The value written to the sysfs file
@@ -3143,7 +3288,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_dvfs_period(struct device *dev,
+static ssize_t dvfs_period_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
@@ -3168,7 +3313,7 @@
 }
 
 /**
- * show_dvfs_period - Show callback for the dvfs_period sysfs entry.
+ * dvfs_period_show - Show callback for the dvfs_period sysfs entry.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf:  The output buffer to receive the GPU information.
@@ -3178,7 +3323,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_dvfs_period(struct device *dev,
+static ssize_t dvfs_period_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -3193,11 +3338,50 @@
 	return ret;
 }
 
-static DEVICE_ATTR(dvfs_period, S_IRUGO | S_IWUSR, show_dvfs_period,
-		set_dvfs_period);
+static DEVICE_ATTR_RW(dvfs_period);
+
+int kbase_pm_lowest_gpu_freq_init(struct kbase_device *kbdev)
+{
+	/* Uses default reference frequency defined in below macro */
+	u64 lowest_freq_khz = DEFAULT_REF_TIMEOUT_FREQ_KHZ;
+
+	/* Only check lowest frequency in cases when OPPs are used and
+	 * present in the device tree.
+	 */
+#ifdef CONFIG_PM_OPP
+	struct dev_pm_opp *opp_ptr;
+	unsigned long found_freq = 0;
+
+	/* find lowest frequency OPP */
+	opp_ptr = dev_pm_opp_find_freq_ceil(kbdev->dev, &found_freq);
+	if (IS_ERR(opp_ptr)) {
+		dev_err(kbdev->dev, "No OPPs found in device tree! Scaling timeouts using %llu kHz",
+			(unsigned long long)lowest_freq_khz);
+	} else {
+#if KERNEL_VERSION(4, 11, 0) <= LINUX_VERSION_CODE
+		dev_pm_opp_put(opp_ptr); /* decrease OPP refcount */
+#endif
+		/* convert found frequency to KHz */
+		found_freq /= 1000;
+
+		/* If lowest frequency in OPP table is still higher
+		 * than the reference, then keep the reference frequency
+		 * as the one to use for scaling .
+		 */
+		if (found_freq < lowest_freq_khz)
+			lowest_freq_khz = found_freq;
+	}
+#else
+	dev_err(kbdev->dev, "No operating-points-v2 node or operating-points property in DT");
+#endif
+
+	kbdev->lowest_gpu_freq_khz = lowest_freq_khz;
+	dev_dbg(kbdev->dev, "Lowest frequency identified is %llu kHz", kbdev->lowest_gpu_freq_khz);
+	return 0;
+}
 
 /**
- * set_pm_poweroff - Store callback for the pm_poweroff sysfs file.
+ * pm_poweroff_store - Store callback for the pm_poweroff sysfs file.
  * @dev:   The device with sysfs file is for
  * @attr:  The attributes of the sysfs file
  * @buf:   The value written to the sysfs file
@@ -3213,7 +3397,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_pm_poweroff(struct device *dev,
+static ssize_t pm_poweroff_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
@@ -3252,7 +3436,7 @@
 }
 
 /**
- * show_pm_poweroff - Show callback for the pm_poweroff sysfs entry.
+ * pm_poweroff_show - Show callback for the pm_poweroff sysfs entry.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf:  The output buffer to receive the GPU information.
@@ -3262,7 +3446,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_pm_poweroff(struct device *dev,
+static ssize_t pm_poweroff_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -3286,80 +3470,10 @@
 	return ret;
 }
 
-static DEVICE_ATTR(pm_poweroff, S_IRUGO | S_IWUSR, show_pm_poweroff,
-		set_pm_poweroff);
-
-#if MALI_USE_CSF
-/**
- * set_idle_hysteresis_time - Store callback for CSF idle_hysteresis_time
- *                            sysfs file.
- * @dev:   The device with sysfs file is for
- * @attr:  The attributes of the sysfs file
- * @buf:   The value written to the sysfs file
- * @count: The number of bytes written to the sysfs file
- *
- * This function is called when the idle_hysteresis_time sysfs file is
- * written to.
- *
- * This file contains values of the idle idle hysteresis duration.
- *
- * Return: @count if the function succeeded. An error code on failure.
- */
-static ssize_t set_idle_hysteresis_time(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct kbase_device *kbdev;
-	u32 dur;
-
-	kbdev = to_kbase_device(dev);
-	if (!kbdev)
-		return -ENODEV;
-
-	if (kstrtou32(buf, 0, &dur)) {
-		dev_err(kbdev->dev, "Couldn't process idle_hysteresis_time write operation.\n"
-				"Use format <idle_hysteresis_time>\n");
-		return -EINVAL;
-	}
-
-	kbase_csf_firmware_set_gpu_idle_hysteresis_time(kbdev, dur);
-
-	return count;
-}
+static DEVICE_ATTR_RW(pm_poweroff);
 
 /**
- * show_idle_hysteresis_time - Show callback for CSF idle_hysteresis_time
- *                             sysfs entry.
- * @dev:  The device this sysfs file is for.
- * @attr: The attributes of the sysfs file.
- * @buf:  The output buffer to receive the GPU information.
- *
- * This function is called to get the current idle hysteresis duration in ms.
- *
- * Return: The number of bytes output to @buf.
- */
-static ssize_t show_idle_hysteresis_time(struct device *dev,
-		struct device_attribute *attr, char * const buf)
-{
-	struct kbase_device *kbdev;
-	ssize_t ret;
-	u32 dur;
-
-	kbdev = to_kbase_device(dev);
-	if (!kbdev)
-		return -ENODEV;
-
-	dur = kbase_csf_firmware_get_gpu_idle_hysteresis_time(kbdev);
-	ret = scnprintf(buf, PAGE_SIZE, "%u\n", dur);
-
-	return ret;
-}
-
-static DEVICE_ATTR(idle_hysteresis_time, S_IRUGO | S_IWUSR,
-		show_idle_hysteresis_time, set_idle_hysteresis_time);
-#endif
-
-/**
- * set_reset_timeout - Store callback for the reset_timeout sysfs file.
+ * reset_timeout_store - Store callback for the reset_timeout sysfs file.
  * @dev:   The device with sysfs file is for
  * @attr:  The attributes of the sysfs file
  * @buf:   The value written to the sysfs file
@@ -3370,7 +3484,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_reset_timeout(struct device *dev,
+static ssize_t reset_timeout_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *kbdev;
@@ -3395,7 +3509,7 @@
 }
 
 /**
- * show_reset_timeout - Show callback for the reset_timeout sysfs entry.
+ * reset_timeout_show - Show callback for the reset_timeout sysfs entry.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf:  The output buffer to receive the GPU information.
@@ -3404,7 +3518,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_reset_timeout(struct device *dev,
+static ssize_t reset_timeout_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -3419,11 +3533,9 @@
 	return ret;
 }
 
-static DEVICE_ATTR(reset_timeout, S_IRUGO | S_IWUSR, show_reset_timeout,
-		set_reset_timeout);
+static DEVICE_ATTR_RW(reset_timeout);
 
-
-static ssize_t show_mem_pool_size(struct device *dev,
+static ssize_t mem_pool_size_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3436,7 +3548,7 @@
 		kbase_mem_pool_debugfs_size);
 }
 
-static ssize_t set_mem_pool_size(struct device *dev,
+static ssize_t mem_pool_size_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3452,10 +3564,9 @@
 	return err ? err : count;
 }
 
-static DEVICE_ATTR(mem_pool_size, S_IRUGO | S_IWUSR, show_mem_pool_size,
-		set_mem_pool_size);
+static DEVICE_ATTR_RW(mem_pool_size);
 
-static ssize_t show_mem_pool_max_size(struct device *dev,
+static ssize_t mem_pool_max_size_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3468,7 +3579,7 @@
 		kbase_mem_pool_debugfs_max_size);
 }
 
-static ssize_t set_mem_pool_max_size(struct device *dev,
+static ssize_t mem_pool_max_size_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3484,11 +3595,10 @@
 	return err ? err : count;
 }
 
-static DEVICE_ATTR(mem_pool_max_size, S_IRUGO | S_IWUSR, show_mem_pool_max_size,
-		set_mem_pool_max_size);
+static DEVICE_ATTR_RW(mem_pool_max_size);
 
 /**
- * show_lp_mem_pool_size - Show size of the large memory pages pool.
+ * lp_mem_pool_size_show - Show size of the large memory pages pool.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf:  The output buffer to receive the pool size.
@@ -3497,7 +3607,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_lp_mem_pool_size(struct device *dev,
+static ssize_t lp_mem_pool_size_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3511,7 +3621,7 @@
 }
 
 /**
- * set_lp_mem_pool_size - Set size of the large memory pages pool.
+ * lp_mem_pool_size_store - Set size of the large memory pages pool.
  * @dev:   The device this sysfs file is for.
  * @attr:  The attributes of the sysfs file.
  * @buf:   The value written to the sysfs file.
@@ -3522,7 +3632,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_lp_mem_pool_size(struct device *dev,
+static ssize_t lp_mem_pool_size_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3538,11 +3648,10 @@
 	return err ? err : count;
 }
 
-static DEVICE_ATTR(lp_mem_pool_size, S_IRUGO | S_IWUSR, show_lp_mem_pool_size,
-		set_lp_mem_pool_size);
+static DEVICE_ATTR_RW(lp_mem_pool_size);
 
 /**
- * show_lp_mem_pool_max_size - Show maximum size of the large memory pages pool.
+ * lp_mem_pool_max_size_show - Show maximum size of the large memory pages pool.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
  * @buf:  The output buffer to receive the pool size.
@@ -3551,7 +3660,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_lp_mem_pool_max_size(struct device *dev,
+static ssize_t lp_mem_pool_max_size_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3565,7 +3674,7 @@
 }
 
 /**
- * set_lp_mem_pool_max_size - Set maximum size of the large memory pages pool.
+ * lp_mem_pool_max_size_store - Set maximum size of the large memory pages pool.
  * @dev:   The device this sysfs file is for.
  * @attr:  The attributes of the sysfs file.
  * @buf:   The value written to the sysfs file.
@@ -3575,7 +3684,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_lp_mem_pool_max_size(struct device *dev,
+static ssize_t lp_mem_pool_max_size_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_device *const kbdev = to_kbase_device(dev);
@@ -3591,8 +3700,7 @@
 	return err ? err : count;
 }
 
-static DEVICE_ATTR(lp_mem_pool_max_size, S_IRUGO | S_IWUSR, show_lp_mem_pool_max_size,
-		set_lp_mem_pool_max_size);
+static DEVICE_ATTR_RW(lp_mem_pool_max_size);
 
 /**
  * show_simplified_mem_pool_max_size - Show the maximum size for the memory
@@ -3793,7 +3901,7 @@
 
 #if !MALI_USE_CSF
 /**
- * show_js_ctx_scheduling_mode - Show callback for js_ctx_scheduling_mode sysfs
+ * js_ctx_scheduling_mode_show - Show callback for js_ctx_scheduling_mode sysfs
  *                               entry.
  * @dev:  The device this sysfs file is for.
  * @attr: The attributes of the sysfs file.
@@ -3803,7 +3911,7 @@
  *
  * Return: The number of bytes output to @buf.
  */
-static ssize_t show_js_ctx_scheduling_mode(struct device *dev,
+static ssize_t js_ctx_scheduling_mode_show(struct device *dev,
 		struct device_attribute *attr, char * const buf)
 {
 	struct kbase_device *kbdev;
@@ -3816,7 +3924,7 @@
 }
 
 /**
- * set_js_ctx_scheduling_mode - Set callback for js_ctx_scheduling_mode sysfs
+ * js_ctx_scheduling_mode_store - Set callback for js_ctx_scheduling_mode sysfs
  *                              entry.
  * @dev:   The device this sysfs file is for.
  * @attr:  The attributes of the sysfs file.
@@ -3829,7 +3937,7 @@
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
-static ssize_t set_js_ctx_scheduling_mode(struct device *dev,
+static ssize_t js_ctx_scheduling_mode_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct kbase_context *kctx;
@@ -3871,11 +3979,7 @@
 	return count;
 }
 
-static DEVICE_ATTR(js_ctx_scheduling_mode, S_IRUGO | S_IWUSR,
-		show_js_ctx_scheduling_mode,
-		set_js_ctx_scheduling_mode);
-
-#ifdef MALI_KBASE_BUILD
+static DEVICE_ATTR_RW(js_ctx_scheduling_mode);
 
 /* Number of entries in serialize_jobs_settings[] */
 #define NR_SERIALIZE_JOBS_SETTINGS 5
@@ -3899,14 +4003,14 @@
  * update_serialize_jobs_setting - Update the serialization setting for the
  *                                 submission of GPU jobs.
  *
- * This function is called when the serialize_jobs sysfs/debugfs file is
- * written to. It matches the requested setting against the available settings
- * and if a matching setting is found updates kbdev->serialize_jobs.
- *
  * @kbdev:  An instance of the GPU platform device, allocated from the probe
  *          method of the driver.
  * @buf:    Buffer containing the value written to the sysfs/debugfs file.
  * @count:  The number of bytes to write to the sysfs/debugfs file.
+ *
+ * This function is called when the serialize_jobs sysfs/debugfs file is
+ * written to. It matches the requested setting against the available settings
+ * and if a matching setting is found updates kbdev->serialize_jobs.
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
@@ -4029,13 +4133,13 @@
 /**
  * show_serialize_jobs_sysfs - Show callback for serialize_jobs sysfs file.
  *
- * This function is called to get the contents of the serialize_jobs sysfs
- * file. This is a list of the available settings with the currently active
- * one surrounded by square brackets.
- *
  * @dev:	The device this sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The output buffer for the sysfs file contents
+ *
+ * This function is called to get the contents of the serialize_jobs sysfs
+ * file. This is a list of the available settings with the currently active
+ * one surrounded by square brackets.
  *
  * Return: The number of bytes output to @buf.
  */
@@ -4071,14 +4175,14 @@
 /**
  * store_serialize_jobs_sysfs - Store callback for serialize_jobs sysfs file.
  *
- * This function is called when the serialize_jobs sysfs file is written to.
- * It matches the requested setting against the available settings and if a
- * matching setting is found updates kbdev->serialize_jobs.
- *
  * @dev:	The device this sysfs file is for
  * @attr:	The attributes of the sysfs file
  * @buf:	The value written to the sysfs file
  * @count:	The number of bytes to write to the sysfs file
+ *
+ * This function is called when the serialize_jobs sysfs file is written to.
+ * It matches the requested setting against the available settings and if a
+ * matching setting is found updates kbdev->serialize_jobs.
  *
  * Return: @count if the function succeeded. An error code on failure.
  */
@@ -4091,7 +4195,6 @@
 
 static DEVICE_ATTR(serialize_jobs, 0600, show_serialize_jobs_sysfs,
 		   store_serialize_jobs_sysfs);
-#endif /* MALI_KBASE_BUILD */
 #endif /* !MALI_USE_CSF */
 
 static void kbasep_protected_mode_hwcnt_disable_worker(struct work_struct *data)
@@ -4187,6 +4290,15 @@
 	kfree(kbdev->protected_dev);
 }
 
+#if IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
+static int kbase_common_reg_map(struct kbase_device *kbdev)
+{
+	return 0;
+}
+static void kbase_common_reg_unmap(struct kbase_device * const kbdev)
+{
+}
+#else /* !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) */
 static int kbase_common_reg_map(struct kbase_device *kbdev)
 {
 	int err = 0;
@@ -4222,6 +4334,7 @@
 		kbdev->reg_size = 0;
 	}
 }
+#endif /* !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI) */
 
 int registers_map(struct kbase_device * const kbdev)
 {
@@ -4350,8 +4463,8 @@
 			kbase_pm_register_access_enable(kbdev);
 			gpu_id = kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_ID));
 			kbase_pm_register_access_disable(kbdev);
-			product_id = KBASE_UBFX32(gpu_id,
-				GPU_ID_VERSION_PRODUCT_ID_SHIFT, 16);
+			product_id =
+				KBASE_UBFX32(gpu_id, KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT, 16);
 			gpu_model_id = GPU_ID2_MODEL_MATCH_VALUE(product_id);
 
 			if (gpu_model_id != GPU_ID2_PRODUCT_TGOX
@@ -4403,10 +4516,9 @@
 	int err = 0;
 	unsigned int i;
 #if defined(CONFIG_REGULATOR)
-	static const char *regulator_names[] = {
-		"mali", "shadercores"
+	static const char * const regulator_names[] = {
+		"mali", "mem"
 	};
-	BUILD_BUG_ON(ARRAY_SIZE(regulator_names) < BASE_MAX_NR_CLOCKS_REGULATORS);
 #endif /* CONFIG_REGULATOR */
 
 	if (!kbdev)
@@ -4422,17 +4534,17 @@
 	 * Any other error is ignored and the driver will continue
 	 * operating with a partial initialization of regulators.
 	 */
-	for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
+	for (i = 0; i < ARRAY_SIZE(regulator_names); i++) {
 		kbdev->regulators[i] = regulator_get_optional(kbdev->dev,
 			regulator_names[i]);
-		if (IS_ERR_OR_NULL(kbdev->regulators[i])) {
+		if (IS_ERR(kbdev->regulators[i])) {
 			err = PTR_ERR(kbdev->regulators[i]);
 			kbdev->regulators[i] = NULL;
 			break;
 		}
 	}
 	if (err == -EPROBE_DEFER) {
-		while ((i > 0) && (i < BASE_MAX_NR_CLOCKS_REGULATORS))
+		while (i > 0)
 			regulator_put(kbdev->regulators[--i]);
 		return err;
 	}
@@ -4453,7 +4565,7 @@
 	 */
 	for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
 		kbdev->clocks[i] = of_clk_get(kbdev->dev->of_node, i);
-		if (IS_ERR_OR_NULL(kbdev->clocks[i])) {
+		if (IS_ERR(kbdev->clocks[i])) {
 			err = PTR_ERR(kbdev->clocks[i]);
 			kbdev->clocks[i] = NULL;
 			break;
@@ -4469,8 +4581,8 @@
 		}
 	}
 	if (err == -EPROBE_DEFER) {
-		while ((i > 0) && (i < BASE_MAX_NR_CLOCKS_REGULATORS)) {
-			clk_unprepare(kbdev->clocks[--i]);
+		while (i > 0) {
+			clk_disable_unprepare(kbdev->clocks[--i]);
 			clk_put(kbdev->clocks[i]);
 		}
 		goto clocks_probe_defer;
@@ -4485,13 +4597,39 @@
 	 * from completing its initialization.
 	 */
 #if defined(CONFIG_PM_OPP)
-#if ((KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE) && \
-	defined(CONFIG_REGULATOR))
+#if defined(CONFIG_REGULATOR)
+#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
 	if (kbdev->nr_regulators > 0) {
-		kbdev->opp_table = dev_pm_opp_set_regulators(kbdev->dev,
-			regulator_names, BASE_MAX_NR_CLOCKS_REGULATORS);
+		kbdev->token = dev_pm_opp_set_regulators(kbdev->dev, regulator_names);
+
+		if (kbdev->token < 0) {
+			err = kbdev->token;
+			goto regulators_probe_defer;
+		}
+
 	}
-#endif /* (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE */
+#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
+	if (kbdev->nr_regulators > 0) {
+		kbdev->opp_table =
+			dev_pm_opp_set_regulators(kbdev->dev, regulator_names,
+						  kbdev->nr_regulators);
+		if (IS_ERR(kbdev->opp_table)) {
+			dev_err(kbdev->dev, "Failed to set regulators\n");
+			return 0;
+		}
+		kbdev->opp_table =
+			dev_pm_opp_register_set_opp_helper(kbdev->dev,
+							   kbase_devfreq_opp_helper);
+		if (IS_ERR(kbdev->opp_table)) {
+			dev_pm_opp_put_regulators(kbdev->opp_table);
+			kbdev->opp_table = NULL;
+			dev_err(kbdev->dev, "Failed to set opp helper\n");
+			return 0;
+		}
+	}
+#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
+#endif /* CONFIG_REGULATOR */
+
 #ifdef CONFIG_ARCH_ROCKCHIP
        err = kbase_platform_rk_init_opp_table(kbdev);
        if (err)
@@ -4502,6 +4640,19 @@
 #endif
 #endif /* CONFIG_PM_OPP */
 	return 0;
+
+#if defined(CONFIG_PM_OPP) &&                                                                      \
+	((KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE) && defined(CONFIG_REGULATOR))
+	for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
+		if (kbdev->clocks[i]) {
+			if (__clk_is_enabled(kbdev->clocks[i]))
+				clk_disable_unprepare(kbdev->clocks[i]);
+			clk_put(kbdev->clocks[i]);
+			kbdev->clocks[i] = NULL;
+		} else
+			break;
+	}
+#endif
 
 clocks_probe_defer:
 #if defined(CONFIG_REGULATOR)
@@ -4518,11 +4669,17 @@
 
 #if defined(CONFIG_PM_OPP)
 	dev_pm_opp_of_remove_table(kbdev->dev);
-#if ((KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE) && \
-	defined(CONFIG_REGULATOR))
+#if defined(CONFIG_REGULATOR)
+#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
+	if (kbdev->token > -EPERM) {
+		dev_pm_opp_unregister_set_opp_helper(kbdev->opp_table);
+		dev_pm_opp_put_regulators(kbdev->token);
+	}
+#elif (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE)
 	if (!IS_ERR_OR_NULL(kbdev->opp_table))
 		dev_pm_opp_put_regulators(kbdev->opp_table);
-#endif /* (KERNEL_VERSION(4, 10, 0) <= LINUX_VERSION_CODE */
+#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
+#endif /* CONFIG_REGULATOR */
 #endif /* CONFIG_PM_OPP */
 
 	for (i = 0; i < BASE_MAX_NR_CLOCKS_REGULATORS; i++) {
@@ -4544,7 +4701,6 @@
 #endif
 }
 
-#ifdef MALI_KBASE_BUILD
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 
 static void trigger_reset(struct kbase_device *kbdev)
@@ -4562,43 +4718,48 @@
 	kbdev = (struct kbase_device *)data; \
 	kbdev->hw_quirks_##type = (u32)val; \
 	trigger_reset(kbdev); \
-	return 0;\
+	return 0; \
 } \
 \
 static int type##_quirks_get(void *data, u64 *val) \
 { \
-	struct kbase_device *kbdev;\
-	kbdev = (struct kbase_device *)data;\
-	*val = kbdev->hw_quirks_##type;\
-	return 0;\
+	struct kbase_device *kbdev; \
+	kbdev = (struct kbase_device *)data; \
+	*val = kbdev->hw_quirks_##type; \
+	return 0; \
 } \
-DEFINE_SIMPLE_ATTRIBUTE(fops_##type##_quirks, type##_quirks_get,\
-		type##_quirks_set, "%llu\n")
+DEFINE_DEBUGFS_ATTRIBUTE(fops_##type##_quirks, type##_quirks_get, \
+			 type##_quirks_set, "%llu\n")
 
 MAKE_QUIRK_ACCESSORS(sc);
 MAKE_QUIRK_ACCESSORS(tiler);
 MAKE_QUIRK_ACCESSORS(mmu);
 MAKE_QUIRK_ACCESSORS(gpu);
 
-static ssize_t kbase_device_debugfs_reset_write(struct file *file,
-		const char __user *ubuf, size_t count, loff_t *ppos)
+/**
+ * kbase_device_debugfs_reset_write() - Reset the GPU
+ *
+ * @data:           Pointer to the Kbase device.
+ * @wait_for_reset: Value written to the file.
+ *
+ * This function will perform the GPU reset, and if the value written to
+ * the file is 1 it will also wait for the reset to complete.
+ *
+ * Return: 0 in case of no error otherwise a negative value.
+ */
+static int kbase_device_debugfs_reset_write(void *data, u64 wait_for_reset)
 {
-	struct kbase_device *kbdev = file->private_data;
-	CSTD_UNUSED(ubuf);
-	CSTD_UNUSED(count);
-	CSTD_UNUSED(ppos);
+	struct kbase_device *kbdev = data;
 
 	trigger_reset(kbdev);
 
-	return count;
+	if (wait_for_reset == 1)
+		return kbase_reset_gpu_wait(kbdev);
+
+	return 0;
 }
 
-static const struct file_operations fops_trigger_reset = {
-	.owner = THIS_MODULE,
-	.open = simple_open,
-	.write = kbase_device_debugfs_reset_write,
-	.llseek = default_llseek,
-};
+DEFINE_DEBUGFS_ATTRIBUTE(fops_trigger_reset, NULL, &kbase_device_debugfs_reset_write, "%llu\n");
 
 /**
  * debugfs_protected_debug_mode_read - "protected_debug_mode" debugfs read
@@ -4682,57 +4843,84 @@
 	.release = single_release,
 };
 
-int kbase_device_debugfs_init(struct kbase_device *kbdev)
+/**
+ * debugfs_ctx_defaults_init - Create the default configuration of new contexts in debugfs
+ * @kbdev: An instance of the GPU platform device, allocated from the probe method of the driver.
+ * Return: A pointer to the last dentry that it tried to create, whether successful or not.
+ *         Could be NULL or encode another error value.
+ */
+static struct dentry *debugfs_ctx_defaults_init(struct kbase_device *const kbdev)
 {
-	struct dentry *debugfs_ctx_defaults_directory;
-	int err;
 	/* prevent unprivileged use of debug file system
 	 * in old kernel version
 	 */
-#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE)
-	/* only for newer kernel version debug file system is safe */
 	const mode_t mode = 0644;
-#else
-	const mode_t mode = 0600;
-#endif
+	struct dentry *dentry = debugfs_create_dir("defaults", kbdev->debugfs_ctx_directory);
+	struct dentry *debugfs_ctx_defaults_directory = dentry;
 
-	kbdev->mali_debugfs_directory = debugfs_create_dir(kbdev->devname,
-			NULL);
-	if (!kbdev->mali_debugfs_directory) {
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Couldn't create mali debugfs ctx defaults directory\n");
+		return dentry;
+	}
+
+	debugfs_create_bool("infinite_cache", mode,
+			debugfs_ctx_defaults_directory,
+			&kbdev->infinite_cache_active_default);
+
+	dentry = debugfs_create_file("mem_pool_max_size", mode, debugfs_ctx_defaults_directory,
+				   &kbdev->mem_pool_defaults.small,
+				   &kbase_device_debugfs_mem_pool_max_size_fops);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create mem_pool_max_size debugfs entry\n");
+		return dentry;
+	}
+
+	dentry = debugfs_create_file("lp_mem_pool_max_size", mode, debugfs_ctx_defaults_directory,
+				   &kbdev->mem_pool_defaults.large,
+				   &kbase_device_debugfs_mem_pool_max_size_fops);
+	if (IS_ERR_OR_NULL(dentry))
+		dev_err(kbdev->dev, "Unable to create lp_mem_pool_max_size debugfs entry\n");
+
+	return dentry;
+}
+
+/**
+ * init_debugfs - Create device-wide debugfs directories and files for the Mali driver
+ * @kbdev: An instance of the GPU platform device, allocated from the probe method of the driver.
+ * Return: A pointer to the last dentry that it tried to create, whether successful or not.
+ *         Could be NULL or encode another error value.
+ */
+static struct dentry *init_debugfs(struct kbase_device *kbdev)
+{
+	struct dentry *dentry = debugfs_create_dir(kbdev->devname, NULL);
+
+	kbdev->mali_debugfs_directory = dentry;
+	if (IS_ERR_OR_NULL(dentry)) {
 		dev_err(kbdev->dev,
 			"Couldn't create mali debugfs directory: %s\n",
 			kbdev->devname);
-		err = -ENOMEM;
-		goto out;
+		return dentry;
 	}
 
-	kbdev->debugfs_ctx_directory = debugfs_create_dir("ctx",
-			kbdev->mali_debugfs_directory);
-	if (!kbdev->debugfs_ctx_directory) {
+	dentry = debugfs_create_dir("ctx", kbdev->mali_debugfs_directory);
+	kbdev->debugfs_ctx_directory = dentry;
+	if (IS_ERR_OR_NULL(dentry)) {
 		dev_err(kbdev->dev, "Couldn't create mali debugfs ctx directory\n");
-		err = -ENOMEM;
-		goto out;
+		return dentry;
 	}
 
-	kbdev->debugfs_instr_directory = debugfs_create_dir("instrumentation",
-			kbdev->mali_debugfs_directory);
-	if (!kbdev->debugfs_instr_directory) {
+	dentry = debugfs_create_dir("instrumentation", kbdev->mali_debugfs_directory);
+	kbdev->debugfs_instr_directory = dentry;
+	if (IS_ERR_OR_NULL(dentry)) {
 		dev_err(kbdev->dev, "Couldn't create mali debugfs instrumentation directory\n");
-		err = -ENOMEM;
-		goto out;
-	}
-
-	debugfs_ctx_defaults_directory = debugfs_create_dir("defaults",
-			kbdev->debugfs_ctx_directory);
-	if (!debugfs_ctx_defaults_directory) {
-		dev_err(kbdev->dev, "Couldn't create mali debugfs ctx defaults directory\n");
-		err = -ENOMEM;
-		goto out;
+		return dentry;
 	}
 
 	kbasep_regs_history_debugfs_init(kbdev);
 
-#if !MALI_USE_CSF
+#if MALI_USE_CSF
+	kbase_debug_csf_fault_debugfs_init(kbdev);
+#else /* MALI_USE_CSF */
 	kbase_debug_job_fault_debugfs_init(kbdev);
 #endif /* !MALI_USE_CSF */
 
@@ -4741,67 +4929,99 @@
 #ifdef CONFIG_MALI_PRFCNT_SET_SELECT_VIA_DEBUG_FS
 	kbase_instr_backend_debugfs_init(kbdev);
 #endif
+	kbase_pbha_debugfs_init(kbdev);
+
 	/* fops_* variables created by invocations of macro
 	 * MAKE_QUIRK_ACCESSORS() above.
 	 */
-	debugfs_create_file("quirks_sc", 0644,
+	dentry = debugfs_create_file("quirks_sc", 0644,
 			kbdev->mali_debugfs_directory, kbdev,
 			&fops_sc_quirks);
-	debugfs_create_file("quirks_tiler", 0644,
-			kbdev->mali_debugfs_directory, kbdev,
-			&fops_tiler_quirks);
-	debugfs_create_file("quirks_mmu", 0644,
-			kbdev->mali_debugfs_directory, kbdev,
-			&fops_mmu_quirks);
-	debugfs_create_file("quirks_gpu", 0644, kbdev->mali_debugfs_directory,
-			    kbdev, &fops_gpu_quirks);
-
-	debugfs_create_bool("infinite_cache", mode,
-			debugfs_ctx_defaults_directory,
-			&kbdev->infinite_cache_active_default);
-
-	debugfs_create_file("mem_pool_max_size", mode,
-			debugfs_ctx_defaults_directory,
-			&kbdev->mem_pool_defaults.small,
-			&kbase_device_debugfs_mem_pool_max_size_fops);
-
-	debugfs_create_file("lp_mem_pool_max_size", mode,
-			debugfs_ctx_defaults_directory,
-			&kbdev->mem_pool_defaults.large,
-			&kbase_device_debugfs_mem_pool_max_size_fops);
-
-	if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE)) {
-		debugfs_create_file("protected_debug_mode", S_IRUGO,
-				kbdev->mali_debugfs_directory, kbdev,
-				&fops_protected_debug_mode);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create quirks_sc debugfs entry\n");
+		return dentry;
 	}
 
-	debugfs_create_file("reset", 0644,
+	dentry = debugfs_create_file("quirks_tiler", 0644,
+			kbdev->mali_debugfs_directory, kbdev,
+			&fops_tiler_quirks);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create quirks_tiler debugfs entry\n");
+		return dentry;
+	}
+
+	dentry = debugfs_create_file("quirks_mmu", 0644,
+			kbdev->mali_debugfs_directory, kbdev,
+			&fops_mmu_quirks);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create quirks_mmu debugfs entry\n");
+		return dentry;
+	}
+
+	dentry = debugfs_create_file("quirks_gpu", 0644, kbdev->mali_debugfs_directory,
+			    kbdev, &fops_gpu_quirks);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create quirks_gpu debugfs entry\n");
+		return dentry;
+	}
+
+	dentry = debugfs_ctx_defaults_init(kbdev);
+	if (IS_ERR_OR_NULL(dentry))
+		return dentry;
+
+	if (kbase_hw_has_feature(kbdev, BASE_HW_FEATURE_PROTECTED_DEBUG_MODE)) {
+		dentry = debugfs_create_file("protected_debug_mode", 0444,
+				kbdev->mali_debugfs_directory, kbdev,
+				&fops_protected_debug_mode);
+		if (IS_ERR_OR_NULL(dentry)) {
+			dev_err(kbdev->dev, "Unable to create protected_debug_mode debugfs entry\n");
+			return dentry;
+		}
+	}
+
+	dentry = debugfs_create_file("reset", 0644,
 			kbdev->mali_debugfs_directory, kbdev,
 			&fops_trigger_reset);
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create reset debugfs entry\n");
+		return dentry;
+	}
 
 	kbase_ktrace_debugfs_init(kbdev);
 
 #ifdef CONFIG_MALI_BIFROST_DEVFREQ
 #if IS_ENABLED(CONFIG_DEVFREQ_THERMAL)
-	if (kbdev->devfreq && !kbdev->model_data)
+	if (kbdev->devfreq && !kbdev->model_data &&
+	    !kbdev->dfc_power.dyn_power_coeff)
 		kbase_ipa_debugfs_init(kbdev);
 #endif /* CONFIG_DEVFREQ_THERMAL */
 #endif /* CONFIG_MALI_BIFROST_DEVFREQ */
 
 #if !MALI_USE_CSF
-	debugfs_create_file("serialize_jobs", S_IRUGO | S_IWUSR,
+	dentry = debugfs_create_file("serialize_jobs", 0644,
 			kbdev->mali_debugfs_directory, kbdev,
 			&kbasep_serialize_jobs_debugfs_fops);
-
+	if (IS_ERR_OR_NULL(dentry)) {
+		dev_err(kbdev->dev, "Unable to create serialize_jobs debugfs entry\n");
+		return dentry;
+	}
+	kbase_timeline_io_debugfs_init(kbdev);
 #endif
 	kbase_dvfs_status_debugfs_init(kbdev);
 
-	return 0;
 
-out:
-	debugfs_remove_recursive(kbdev->mali_debugfs_directory);
-	return err;
+	return dentry;
+}
+
+int kbase_device_debugfs_init(struct kbase_device *kbdev)
+{
+	struct dentry *dentry = init_debugfs(kbdev);
+
+	if (IS_ERR_OR_NULL(dentry)) {
+		debugfs_remove_recursive(kbdev->mali_debugfs_directory);
+		return IS_ERR(dentry) ? PTR_ERR(dentry) : -ENOMEM;
+	}
+	return 0;
 }
 
 void kbase_device_debugfs_term(struct kbase_device *kbdev)
@@ -4809,7 +5029,6 @@
 	debugfs_remove_recursive(kbdev->mali_debugfs_directory);
 }
 #endif /* CONFIG_DEBUG_FS */
-#endif /* MALI_KBASE_BUILD */
 
 int kbase_device_coherency_init(struct kbase_device *kbdev)
 {
@@ -4817,12 +5036,13 @@
 	u32 supported_coherency_bitmap =
 		kbdev->gpu_props.props.raw_props.coherency_mode;
 	const void *coherency_override_dts;
+	bool dma_coherent;
 	u32 override_coherency, gpu_id;
 	unsigned int prod_id;
 
 	gpu_id = kbdev->gpu_props.props.raw_props.gpu_id;
 	gpu_id &= GPU_ID_VERSION_PRODUCT_ID;
-	prod_id = gpu_id >> GPU_ID_VERSION_PRODUCT_ID_SHIFT;
+	prod_id = gpu_id >> KBASE_GPU_ID_VERSION_PRODUCT_ID_SHIFT;
 
 	/* Only for tMIx :
 	 * (COHERENCY_ACE_LITE | COHERENCY_ACE) was incorrectly
@@ -4841,12 +5061,23 @@
 
 	/* device tree may override the coherency */
 #if IS_ENABLED(CONFIG_OF)
+	/* treat "dma-coherency" as a synonym for ACE-lite */
+	dma_coherent = of_dma_is_coherent(kbdev->dev->of_node);
 	coherency_override_dts = of_get_property(kbdev->dev->of_node,
 						"system-coherency",
 						NULL);
-	if (coherency_override_dts) {
-
-		override_coherency = be32_to_cpup(coherency_override_dts);
+	if (coherency_override_dts || dma_coherent) {
+		if (coherency_override_dts) {
+			override_coherency = be32_to_cpup(coherency_override_dts);
+			if (dma_coherent && override_coherency != COHERENCY_ACE_LITE) {
+				dev_err(kbdev->dev,
+					"system-coherency needs to be 0 when dma-coherent is set\n");
+				return -EINVAL;
+			}
+		} else {
+			/* dma-coherent set and system-coherency not specified */
+			override_coherency = COHERENCY_ACE_LITE;
+		}
 
 #if MALI_USE_CSF && !IS_ENABLED(CONFIG_MALI_BIFROST_NO_MALI)
 		/* ACE coherency mode is not supported by Driver on CSF GPUs.
@@ -4954,8 +5185,7 @@
 	return ret;
 }
 
-static DEVICE_ATTR(csg_scheduling_period, 0644, csg_scheduling_period_show,
-		   csg_scheduling_period_store);
+static DEVICE_ATTR_RW(csg_scheduling_period);
 
 /**
  * fw_timeout_store - Store callback for the fw_timeout sysfs file.
@@ -4983,10 +5213,11 @@
 
 	ret = kstrtouint(buf, 0, &fw_timeout);
 	if (ret || fw_timeout == 0) {
-		dev_err(kbdev->dev, "%s\n%s\n%u",
-			"Couldn't process fw_timeout write operation.",
-			"Use format 'fw_timeout_ms', and fw_timeout_ms > 0",
-			FIRMWARE_PING_INTERVAL_MS);
+		dev_err(kbdev->dev,
+			"Couldn't process fw_timeout write operation.\n"
+			"Use format 'fw_timeout_ms', and fw_timeout_ms > 0\n"
+			"Default fw_timeout: %u",
+			kbase_get_timeout_ms(kbdev, CSF_FIRMWARE_PING_TIMEOUT));
 		return -EINVAL;
 	}
 
@@ -5023,7 +5254,133 @@
 	return ret;
 }
 
-static DEVICE_ATTR(fw_timeout, 0644, fw_timeout_show, fw_timeout_store);
+static DEVICE_ATTR_RW(fw_timeout);
+
+/**
+ * idle_hysteresis_time_store - Store callback for CSF idle_hysteresis_time
+ *                            sysfs file.
+ * @dev:   The device with sysfs file is for
+ * @attr:  The attributes of the sysfs file
+ * @buf:   The value written to the sysfs file
+ * @count: The number of bytes written to the sysfs file
+ *
+ * This function is called when the idle_hysteresis_time sysfs file is
+ * written to.
+ *
+ * This file contains values of the idle hysteresis duration.
+ *
+ * Return: @count if the function succeeded. An error code on failure.
+ */
+static ssize_t idle_hysteresis_time_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct kbase_device *kbdev;
+	u32 dur = 0;
+
+	kbdev = to_kbase_device(dev);
+	if (!kbdev)
+		return -ENODEV;
+
+	if (kstrtou32(buf, 0, &dur)) {
+		dev_err(kbdev->dev, "Couldn't process idle_hysteresis_time write operation.\n"
+				"Use format <idle_hysteresis_time>\n");
+		return -EINVAL;
+	}
+
+	kbase_csf_firmware_set_gpu_idle_hysteresis_time(kbdev, dur);
+
+	return count;
+}
+
+/**
+ * idle_hysteresis_time_show - Show callback for CSF idle_hysteresis_time
+ *                             sysfs entry.
+ * @dev:  The device this sysfs file is for.
+ * @attr: The attributes of the sysfs file.
+ * @buf:  The output buffer to receive the GPU information.
+ *
+ * This function is called to get the current idle hysteresis duration in ms.
+ *
+ * Return: The number of bytes output to @buf.
+ */
+static ssize_t idle_hysteresis_time_show(struct device *dev,
+		struct device_attribute *attr, char * const buf)
+{
+	struct kbase_device *kbdev;
+	ssize_t ret;
+	u32 dur;
+
+	kbdev = to_kbase_device(dev);
+	if (!kbdev)
+		return -ENODEV;
+
+	dur = kbase_csf_firmware_get_gpu_idle_hysteresis_time(kbdev);
+	ret = scnprintf(buf, PAGE_SIZE, "%u\n", dur);
+
+	return ret;
+}
+
+static DEVICE_ATTR_RW(idle_hysteresis_time);
+
+/**
+ * mcu_shader_pwroff_timeout_show - Get the MCU shader Core power-off time value.
+ *
+ * @dev:  The device this sysfs file is for.
+ * @attr: The attributes of the sysfs file.
+ * @buf:  The output buffer for the sysfs file contents
+ *
+ * Get the internally recorded MCU shader Core power-off (nominal) timeout value.
+ * The unit of the value is in micro-seconds.
+ *
+ * Return: The number of bytes output to @buf if the
+ *         function succeeded. A Negative value on failure.
+ */
+static ssize_t mcu_shader_pwroff_timeout_show(struct device *dev, struct device_attribute *attr,
+					      char *const buf)
+{
+	struct kbase_device *kbdev = dev_get_drvdata(dev);
+	u32 pwroff;
+
+	if (!kbdev)
+		return -ENODEV;
+
+	pwroff = kbase_csf_firmware_get_mcu_core_pwroff_time(kbdev);
+	return scnprintf(buf, PAGE_SIZE, "%u\n", pwroff);
+}
+
+/**
+ * mcu_shader_pwroff_timeout_store - Set the MCU shader core power-off time value.
+ *
+ * @dev:   The device with sysfs file is for
+ * @attr:  The attributes of the sysfs file
+ * @buf:   The value written to the sysfs file
+ * @count: The number of bytes to write to the sysfs file
+ *
+ * The duration value (unit: micro-seconds) for configuring MCU Shader Core
+ * timer, when the shader cores' power transitions are delegated to the
+ * MCU (normal operational mode)
+ *
+ * Return: @count if the function succeeded. An error code on failure.
+ */
+static ssize_t mcu_shader_pwroff_timeout_store(struct device *dev, struct device_attribute *attr,
+					       const char *buf, size_t count)
+{
+	struct kbase_device *kbdev = dev_get_drvdata(dev);
+	u32 dur;
+
+	if (!kbdev)
+		return -ENODEV;
+
+	if (kstrtouint(buf, 0, &dur))
+		return -EINVAL;
+
+	kbase_csf_firmware_set_mcu_core_pwroff_time(kbdev, dur);
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(mcu_shader_pwroff_timeout);
+
 #endif /* MALI_USE_CSF */
 
 static struct attribute *kbase_scheduling_attrs[] = {
@@ -5047,15 +5404,14 @@
 	&dev_attr_gpuinfo.attr,
 	&dev_attr_dvfs_period.attr,
 	&dev_attr_pm_poweroff.attr,
-#if MALI_USE_CSF
-	&dev_attr_idle_hysteresis_time.attr,
-#endif
 	&dev_attr_reset_timeout.attr,
 #if !MALI_USE_CSF
 	&dev_attr_js_scheduling_period.attr,
 #else
 	&dev_attr_csg_scheduling_period.attr,
 	&dev_attr_fw_timeout.attr,
+	&dev_attr_idle_hysteresis_time.attr,
+	&dev_attr_mcu_shader_pwroff_timeout.attr,
 #endif /* !MALI_USE_CSF */
 	&dev_attr_power_policy.attr,
 	&dev_attr_core_mask.attr,
@@ -5186,8 +5542,15 @@
 	}
 
 	kbdev->dev = &pdev->dev;
-	dev_set_drvdata(kbdev->dev, kbdev);
 
+#if (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE)
+	kbdev->token = -EPERM;
+#endif /* (KERNEL_VERSION(6, 0, 0) <= LINUX_VERSION_CODE) */
+
+	dev_set_drvdata(kbdev->dev, kbdev);
+#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
+	mutex_lock(&kbase_probe_mutex);
+#endif
 	err = kbase_device_init(kbdev);
 
 	if (err) {
@@ -5199,12 +5562,16 @@
 
 		dev_set_drvdata(kbdev->dev, NULL);
 		kbase_device_free(kbdev);
+#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
+		mutex_unlock(&kbase_probe_mutex);
+#endif
 	} else {
-#ifdef MALI_KBASE_BUILD
 		dev_info(kbdev->dev,
 			"Probed as %s\n", dev_name(kbdev->mdev.this_device));
-#endif /* MALI_KBASE_BUILD */
 		kbase_increment_device_id();
+#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
+		mutex_unlock(&kbase_probe_mutex);
+#endif
 #ifdef CONFIG_MALI_ARBITER_SUPPORT
 		mutex_lock(&kbdev->pm.lock);
 		kbase_arbiter_pm_vm_event(kbdev, KBASE_VM_GPU_INITIALIZED_EVT);
@@ -5220,11 +5587,11 @@
 /**
  * kbase_device_suspend - Suspend callback from the OS.
  *
- * This is called by Linux when the device should suspend.
- *
  * @dev:  The device to suspend
  *
- * Return: A standard Linux error code
+ * This is called by Linux when the device should suspend.
+ *
+ * Return: A standard Linux error code on failure, 0 otherwise.
  */
 static int kbase_device_suspend(struct device *dev)
 {
@@ -5233,7 +5600,10 @@
 	if (!kbdev)
 		return -ENODEV;
 
-	kbase_pm_suspend(kbdev);
+	if (kbase_pm_suspend(kbdev)) {
+		dev_warn(kbdev->dev, "Abort suspend as GPU suspension failed");
+		return -EBUSY;
+	}
 
 #ifdef CONFIG_MALI_BIFROST_DVFS
 	kbase_pm_metrics_stop(kbdev);
@@ -5246,15 +5616,27 @@
 		flush_workqueue(kbdev->devfreq_queue.workq);
 	}
 #endif
+
+#ifdef CONFIG_ARCH_ROCKCHIP
+	kbase_platform_rk_enable_regulator(kbdev);
+#endif
+
+#ifdef KBASE_PM_RUNTIME
+	if (kbdev->is_runtime_resumed) {
+		if (kbdev->pm.backend.callback_power_runtime_off)
+			kbdev->pm.backend.callback_power_runtime_off(kbdev);
+	}
+#endif /* KBASE_PM_RUNTIME */
+
 	return 0;
 }
 
 /**
  * kbase_device_resume - Resume callback from the OS.
  *
- * This is called by Linux when the device should resume from suspension.
- *
  * @dev:  The device to resume
+ *
+ * This is called by Linux when the device should resume from suspension.
  *
  * Return: A standard Linux error code
  */
@@ -5265,6 +5647,13 @@
 	if (!kbdev)
 		return -ENODEV;
 
+#ifdef KBASE_PM_RUNTIME
+	if (kbdev->is_runtime_resumed) {
+		if (kbdev->pm.backend.callback_power_runtime_on)
+			kbdev->pm.backend.callback_power_runtime_on(kbdev);
+	}
+#endif /* KBASE_PM_RUNTIME */
+
 	kbase_pm_resume(kbdev);
 
 #ifdef CONFIG_MALI_BIFROST_DVFS
@@ -5273,25 +5662,25 @@
 
 #ifdef CONFIG_MALI_BIFROST_DEVFREQ
 	dev_dbg(dev, "Callback %s\n", __func__);
-	if (kbdev->devfreq) {
-		mutex_lock(&kbdev->pm.lock);
-		if (kbdev->pm.active_count > 0)
-			kbase_devfreq_enqueue_work(kbdev, DEVFREQ_WORK_RESUME);
-		mutex_unlock(&kbdev->pm.lock);
-		flush_workqueue(kbdev->devfreq_queue.workq);
-	}
+	if (kbdev->devfreq)
+		kbase_devfreq_enqueue_work(kbdev, DEVFREQ_WORK_RESUME);
 #endif
+
+#if !MALI_USE_CSF
+	kbase_enable_quick_reset(kbdev);
+#endif
+
 	return 0;
 }
 
 /**
  * kbase_device_runtime_suspend - Runtime suspend callback from the OS.
  *
+ * @dev:  The device to suspend
+ *
  * This is called by Linux when the device should prepare for a condition in
  * which it will not be able to communicate with the CPU(s) and RAM due to
  * power management.
- *
- * @dev:  The device to suspend
  *
  * Return: A standard Linux error code
  */
@@ -5299,11 +5688,19 @@
 static int kbase_device_runtime_suspend(struct device *dev)
 {
 	struct kbase_device *kbdev = to_kbase_device(dev);
+	int ret = 0;
 
 	if (!kbdev)
 		return -ENODEV;
 
 	dev_dbg(dev, "Callback %s\n", __func__);
+	KBASE_KTRACE_ADD(kbdev, PM_RUNTIME_SUSPEND_CALLBACK, NULL, 0);
+
+#if MALI_USE_CSF
+	ret = kbase_pm_handle_runtime_suspend(kbdev);
+	if (ret)
+		return ret;
+#endif
 
 #ifdef CONFIG_MALI_BIFROST_DVFS
 	kbase_pm_metrics_stop(kbdev);
@@ -5316,18 +5713,19 @@
 
 	if (kbdev->pm.backend.callback_power_runtime_off) {
 		kbdev->pm.backend.callback_power_runtime_off(kbdev);
+		kbdev->is_runtime_resumed = false;
 		dev_dbg(dev, "runtime suspend\n");
 	}
-	return 0;
+	return ret;
 }
 #endif /* KBASE_PM_RUNTIME */
 
 /**
  * kbase_device_runtime_resume - Runtime resume callback from the OS.
  *
- * This is called by Linux when the device should go into a fully active state.
- *
  * @dev:  The device to suspend
+ *
+ * This is called by Linux when the device should go into a fully active state.
  *
  * Return: A standard Linux error code
  */
@@ -5342,8 +5740,10 @@
 		return -ENODEV;
 
 	dev_dbg(dev, "Callback %s\n", __func__);
+	// KBASE_KTRACE_ADD(kbdev, PM_RUNTIME_RESUME_CALLBACK, NULL, 0);
 	if (kbdev->pm.backend.callback_power_runtime_on) {
 		ret = kbdev->pm.backend.callback_power_runtime_on(kbdev);
+		kbdev->is_runtime_resumed = true;
 		dev_dbg(dev, "runtime resume\n");
 	}
 
@@ -5405,10 +5805,11 @@
 };
 
 #if IS_ENABLED(CONFIG_OF)
-static const struct of_device_id kbase_dt_ids[] = {
-	{ .compatible = "arm,mali-bifrost" },
-	{ /* sentinel */ }
-};
+static const struct of_device_id kbase_dt_ids[] = { { .compatible = "arm,malit6xx" },
+						    { .compatible = "arm,mali-midgard" },
+						    { .compatible = "arm,mali-bifrost" },
+						    { .compatible = "arm,mali-valhall" },
+						    { /* sentinel */ } };
 MODULE_DEVICE_TABLE(of, kbase_dt_ids);
 #endif
 
@@ -5423,26 +5824,29 @@
 	},
 };
 
-/*
- * The driver will not provide a shortcut to create the Mali platform device
- * anymore when using Device Tree.
- */
-#if IS_ENABLED(CONFIG_OF)
+#if (KERNEL_VERSION(5, 3, 0) > LINUX_VERSION_CODE) && IS_ENABLED(CONFIG_OF)
 module_platform_driver(kbase_platform_driver);
 #else
-
 static int __init kbase_driver_init(void)
 {
 	int ret;
 
+#if (KERNEL_VERSION(5, 3, 0) <= LINUX_VERSION_CODE)
+	mutex_init(&kbase_probe_mutex);
+#endif
+
+#ifndef CONFIG_OF
 	ret = kbase_platform_register();
 	if (ret)
 		return ret;
-
+#endif
 	ret = platform_driver_register(&kbase_platform_driver);
-
-	if (ret)
+#ifndef CONFIG_OF
+	if (ret) {
 		kbase_platform_unregister();
+		return ret;
+	}
+#endif
 
 	return ret;
 }
@@ -5450,19 +5854,20 @@
 static void __exit kbase_driver_exit(void)
 {
 	platform_driver_unregister(&kbase_platform_driver);
+#ifndef CONFIG_OF
 	kbase_platform_unregister();
+#endif
 }
 
 module_init(kbase_driver_init);
 module_exit(kbase_driver_exit);
-
-#endif /* CONFIG_OF */
-
+#endif
 MODULE_LICENSE("GPL");
 MODULE_VERSION(MALI_RELEASE_NAME " (UK version " \
 		__stringify(BASE_UK_VERSION_MAJOR) "." \
 		__stringify(BASE_UK_VERSION_MINOR) ")");
 MODULE_SOFTDEP("pre: memory_group_manager");
+MODULE_INFO(import_ns, "DMA_BUF");
 
 #define CREATE_TRACE_POINTS
 /* Create the trace points (otherwise we just get code to call a tracepoint) */
@@ -5492,7 +5897,7 @@
 	trace_mali_page_fault_insert_pages(dev_id, event, value);
 }
 
-void kbase_trace_mali_total_alloc_pages_change(u32 dev_id, long long int event)
+void kbase_trace_mali_total_alloc_pages_change(u32 dev_id, long long event)
 {
 	trace_mali_total_alloc_pages_change(dev_id, event);
 }

--
Gitblit v1.6.2