From 558d68d15e0aa01b327974e0960d096901127a8a Mon Sep 17 00:00:00 2001
From: Drew Fustini <dfustini@baylibre.com>
Date: Fri, 7 Apr 2023 17:14:49 -0700
Subject: [PATCH] DO_NOT_MERGE riscv: platform driver to set sqoscfg for
 current task

---
 drivers/platform/Makefile        |  1 +
 drivers/platform/qoscfg/Makefile |  3 ++
 drivers/platform/qoscfg/qoscfg.c | 86 ++++++++++++++++++++++++++++++++
 3 files changed, 90 insertions(+)
 create mode 100644 drivers/platform/qoscfg/Makefile
 create mode 100644 drivers/platform/qoscfg/qoscfg.c

diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 41640172975a7..4615ae9bd8647 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_OLPC_EC)		+= olpc/
 obj-$(CONFIG_GOLDFISH)		+= goldfish/
 obj-$(CONFIG_CHROME_PLATFORMS)	+= chrome/
 obj-$(CONFIG_SURFACE_PLATFORMS)	+= surface/
+obj-y				+= qoscfg/
diff --git a/drivers/platform/qoscfg/Makefile b/drivers/platform/qoscfg/Makefile
new file mode 100644
index 0000000000000..6bc94c003ccbc
--- /dev/null
+++ b/drivers/platform/qoscfg/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+obj-y	+= qoscfg.o
diff --git a/drivers/platform/qoscfg/qoscfg.c b/drivers/platform/qoscfg/qoscfg.c
new file mode 100644
index 0000000000000..ad3ee1c901034
--- /dev/null
+++ b/drivers/platform/qoscfg/qoscfg.c
@@ -0,0 +1,86 @@
+/*
+ * DO NOT MERGE
+ * Simple test driver to set thread.sqoscfg for the current task
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sysfs.h>
+#include <asm/qos.h>
+
+static struct kobject *thread_qoscfg_kobj;
+
+/* Sysfs file read function */
+static ssize_t thread_qoscfg_value_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
+{
+	struct task_struct *task = current;
+	u32 thread_qoscfg;
+
+	thread_qoscfg = READ_ONCE(task->thread.sqoscfg);
+	trace_printk("DEBUG %s(): task->pid=%d thread_qoscfg=%d", __func__, task->pid, thread_qoscfg);
+
+	return sprintf(buf, "%d\n", thread_qoscfg);
+}
+
+/* Sysfs file write function */
+static ssize_t thread_qoscfg_value_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
+{
+	struct task_struct *task = current;
+	u32 thread_qoscfg;
+	u32 old_thread_qoscfg;
+	int value;
+
+	if (kstrtoint(buf, 10, &value) < 0)
+		return -EINVAL;
+	trace_printk("DEBUG %s(): task->pid=%d value=%d", __func__, task->pid, value);
+
+	old_thread_qoscfg = READ_ONCE(task->thread.sqoscfg);
+	trace_printk("DEBUG %s(): old_thread.sqoscfg=0x%x", __func__, old_thread_qoscfg);
+
+	trace_printk("DEBUG %s(): write value to thread.sqoscfg=0x%x for pid=%d", __func__, value, task->pid);
+	WRITE_ONCE(task->thread.sqoscfg, value);
+
+	thread_qoscfg = READ_ONCE(task->thread.sqoscfg);
+	trace_printk("DEBUG %s(): read thread.sqoscfg=%d for pid=%d", __func__, thread_qoscfg, task->pid);
+
+	return count;
+}
+
+/* Sysfs attributes */
+static struct kobj_attribute thread_qoscfg_value_attr = __ATTR(thread_qoscfg_value, 0660, thread_qoscfg_value_show, thread_qoscfg_value_store);
+
+/* Initialize the module */
+static int __init thread_qoscfg_init(void)
+{
+	int error = 0;
+
+	/* Create a kobject */
+	thread_qoscfg_kobj = kobject_create_and_add("thread_qoscfg", kernel_kobj);
+	if (!thread_qoscfg_kobj)
+		return -ENOMEM;
+
+	/* Create sysfs file attributes */
+	error = sysfs_create_file(thread_qoscfg_kobj, &thread_qoscfg_value_attr.attr);
+	if (error) {
+		kobject_put(thread_qoscfg_kobj);
+		return error;
+	}
+
+	return 0;
+}
+
+/* Cleanup the module */
+static void __exit thread_qoscfg_exit(void)
+{
+	/* Remove sysfs file attributes */
+	sysfs_remove_file(thread_qoscfg_kobj, &thread_qoscfg_value_attr.attr);
+
+	/* Remove the kobject */
+	kobject_put(thread_qoscfg_kobj);
+}
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Drew Fustini");
+MODULE_DESCRIPTION("Test sysfs module for RISC-V Ssqosid");
+module_init(thread_qoscfg_init);
+module_exit(thread_qoscfg_exit);
+
-- 
GitLab