From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 19 Dec 2024 01:47:39 +0000
Subject: [PATCH] add wifi6 8852be driver

---
 kernel/drivers/base/devtmpfs.c |  151 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 94 insertions(+), 57 deletions(-)

diff --git a/kernel/drivers/base/devtmpfs.c b/kernel/drivers/base/devtmpfs.c
index f776807..b5cbaa6 100644
--- a/kernel/drivers/base/devtmpfs.c
+++ b/kernel/drivers/base/devtmpfs.c
@@ -25,15 +25,13 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/init_syscalls.h>
+#include <uapi/linux/mount.h>
 #include "base.h"
 
 static struct task_struct *thread;
 
-#if defined CONFIG_DEVTMPFS_MOUNT
-static int mount_dev = 1;
-#else
-static int mount_dev;
-#endif
+static int __initdata mount_dev = IS_ENABLED(CONFIG_DEVTMPFS_MOUNT);
 
 static DEFINE_SPINLOCK(req_lock);
 
@@ -55,20 +53,39 @@
 }
 __setup("devtmpfs.mount=", mount_param);
 
-static struct dentry *dev_mount(struct file_system_type *fs_type, int flags,
+static struct vfsmount *mnt;
+
+static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags,
 		      const char *dev_name, void *data)
 {
-#ifdef CONFIG_TMPFS
-	return mount_single(fs_type, flags, data, shmem_fill_super);
-#else
-	return mount_single(fs_type, flags, data, ramfs_fill_super);
-#endif
+	struct super_block *s = mnt->mnt_sb;
+	int err;
+
+	atomic_inc(&s->s_active);
+	down_write(&s->s_umount);
+	err = reconfigure_single(s, flags, data);
+	if (err < 0) {
+		deactivate_locked_super(s);
+		return ERR_PTR(err);
+	}
+	return dget(s->s_root);
 }
+
+static struct file_system_type internal_fs_type = {
+	.name = "devtmpfs",
+#ifdef CONFIG_TMPFS
+	.init_fs_context = shmem_init_fs_context,
+	.parameters	= shmem_fs_parameters,
+#else
+	.init_fs_context = ramfs_init_fs_context,
+	.parameters	= ramfs_fs_parameters,
+#endif
+	.kill_sb = kill_litter_super,
+};
 
 static struct file_system_type dev_fs_type = {
 	.name = "devtmpfs",
-	.mount = dev_mount,
-	.kill_sb = kill_litter_super,
+	.mount = public_dev_mount,
 };
 
 #ifdef CONFIG_BLOCK
@@ -79,6 +96,23 @@
 #else
 static inline int is_blockdev(struct device *dev) { return 0; }
 #endif
+
+static int devtmpfs_submit_req(struct req *req, const char *tmp)
+{
+	init_completion(&req->done);
+
+	spin_lock(&req_lock);
+	req->next = requests;
+	requests = req;
+	spin_unlock(&req_lock);
+
+	wake_up_process(thread);
+	wait_for_completion(&req->done);
+
+	kfree(tmp);
+
+	return req->err;
+}
 
 int devtmpfs_create_node(struct device *dev)
 {
@@ -104,19 +138,7 @@
 
 	req.dev = dev;
 
-	init_completion(&req.done);
-
-	spin_lock(&req_lock);
-	req.next = requests;
-	requests = &req;
-	spin_unlock(&req_lock);
-
-	wake_up_process(thread);
-	wait_for_completion(&req.done);
-
-	kfree(tmp);
-
-	return req.err;
+	return devtmpfs_submit_req(&req, tmp);
 }
 
 int devtmpfs_delete_node(struct device *dev)
@@ -134,18 +156,7 @@
 	req.mode = 0;
 	req.dev = dev;
 
-	init_completion(&req.done);
-
-	spin_lock(&req_lock);
-	req.next = requests;
-	requests = &req;
-	spin_unlock(&req_lock);
-
-	wake_up_process(thread);
-	wait_for_completion(&req.done);
-
-	kfree(tmp);
-	return req.err;
+	return devtmpfs_submit_req(&req, tmp);
 }
 
 static int dev_mkdir(const char *name, umode_t mode)
@@ -252,7 +263,7 @@
 
 static int delete_path(const char *nodepath)
 {
-	const char *path;
+	char *path;
 	int err = 0;
 
 	path = kstrdup(nodepath, GFP_KERNEL);
@@ -346,7 +357,7 @@
  * If configured, or requested by the commandline, devtmpfs will be
  * auto-mounted after the kernel mounted the root filesystem.
  */
-int devtmpfs_mount(const char *mntdir)
+int __init devtmpfs_mount(void)
 {
 	int err;
 
@@ -356,8 +367,7 @@
 	if (!thread)
 		return 0;
 
-	err = ksys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT,
-			 NULL);
+	err = init_mount("devtmpfs", "dev", "devtmpfs", MS_SILENT, NULL);
 	if (err)
 		printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
 	else
@@ -376,19 +386,8 @@
 		return handle_remove(name, dev);
 }
 
-static int devtmpfsd(void *p)
+static void __noreturn devtmpfs_work_loop(void)
 {
-	char options[] = "mode=0755";
-	int *err = p;
-	*err = ksys_unshare(CLONE_NEWNS);
-	if (*err)
-		goto out;
-	*err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options);
-	if (*err)
-		goto out;
-	ksys_chdir("/.."); /* will traverse into overmounted root */
-	ksys_chroot(".");
-	complete(&setup_done);
 	while (1) {
 		spin_lock(&req_lock);
 		while (requests) {
@@ -408,10 +407,39 @@
 		spin_unlock(&req_lock);
 		schedule();
 	}
-	return 0;
+}
+
+static int __init devtmpfs_setup(void *p)
+{
+	int err;
+
+	err = ksys_unshare(CLONE_NEWNS);
+	if (err)
+		goto out;
+	err = init_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL);
+	if (err)
+		goto out;
+	init_chdir("/.."); /* will traverse into overmounted root */
+	init_chroot(".");
 out:
+	*(int *)p = err;
+	return err;
+}
+
+/*
+ * The __ref is because devtmpfs_setup needs to be __init for the routines it
+ * calls.  That call is done while devtmpfs_init, which is marked __init,
+ * synchronously waits for it to complete.
+ */
+static int __ref devtmpfsd(void *p)
+{
+	int err = devtmpfs_setup(p);
+
 	complete(&setup_done);
-	return *err;
+	if (err)
+		return err;
+	devtmpfs_work_loop();
+	return 0;
 }
 
 /*
@@ -420,7 +448,16 @@
  */
 int __init devtmpfs_init(void)
 {
-	int err = register_filesystem(&dev_fs_type);
+	char opts[] = "mode=0755";
+	int err;
+
+	mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts);
+	if (IS_ERR(mnt)) {
+		printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n",
+				PTR_ERR(mnt));
+		return PTR_ERR(mnt);
+	}
+	err = register_filesystem(&dev_fs_type);
 	if (err) {
 		printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
 		       "type %i\n", err);

--
Gitblit v1.6.2