[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250114095527.23722-4-zhaoqunqin@loongson.cn>
Date: Tue, 14 Jan 2025 17:55:27 +0800
From: Qunqin Zhao <zhaoqunqin@...ngson.cn>
To: lee@...nel.org,
herbert@...dor.apana.org.au,
gregkh@...uxfoundation.org
Cc: linux-kernel@...r.kernel.org,
loongarch@...ts.linux.dev,
davem@...emloft.net,
linux-crypto@...r.kernel.org,
arnd@...db.de,
derek.kiernan@....com,
dragan.cvetic@....com,
Qunqin Zhao <zhaoqunqin@...ngson.cn>,
Yinggang Gu <guyinggang@...ngson.cn>
Subject: [PATCH v1 3/3] misc: ls6000se-sdf: Add driver for Loongson 6000SE SDF
Loongson Secure Device Function device supports the functions specified
in "GB/T 36322-2018". This driver is only responsible for sending user
data to SDF devices or returning SDF device data to users.
Co-developed-by: Yinggang Gu <guyinggang@...ngson.cn>
Signed-off-by: Yinggang Gu <guyinggang@...ngson.cn>
Signed-off-by: Qunqin Zhao <zhaoqunqin@...ngson.cn>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 9 +++
drivers/misc/Makefile | 1 +
drivers/misc/ls6000se-sdf.c | 123 ++++++++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+)
create mode 100644 drivers/misc/ls6000se-sdf.c
diff --git a/MAINTAINERS b/MAINTAINERS
index e65a7f4ea4..e313e0daf8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13485,6 +13485,7 @@ M: Qunqin Zhao <zhaoqunqin@...ngson.com>
L: linux-crypto@...r.kernel.org
S: Maintained
F: drivers/crypto/loongson/
+F: drivers/misc/ls6000se-sdf.c
LOONGSON-2 APB DMA DRIVER
M: Binbin Zhou <zhoubinbin@...ngson.cn>
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 09cbe3f0ab..10a3ea59a1 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -634,6 +634,15 @@ config MCHP_LAN966X_PCI
- lan966x-miim (MDIO_MSCC_MIIM)
- lan966x-switch (LAN966X_SWITCH)
+config LS6000SE_SDF
+ tristate "Loongson Secure Device Function driver"
+ depends on MFD_LS6000SE
+ help
+ Loongson Secure Device Function device is the child device of Loongson
+ Security Module device, it supports the functions specified in
+ GB/T 36322-2018. This driver will use the interface of Loongson Security
+ Module driver.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 40bf953185..b273ec7802 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -74,3 +74,4 @@ lan966x-pci-objs := lan966x_pci.o
lan966x-pci-objs += lan966x_pci.dtbo.o
obj-$(CONFIG_MCHP_LAN966X_PCI) += lan966x-pci.o
obj-y += keba/
+obj-$(CONFIG_LS6000SE_SDF) += ls6000se-sdf.o
diff --git a/drivers/misc/ls6000se-sdf.c b/drivers/misc/ls6000se-sdf.c
new file mode 100644
index 0000000000..646d54b6e4
--- /dev/null
+++ b/drivers/misc/ls6000se-sdf.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (C) 2025 Loongson Technology Corporation Limited */
+
+#include <linux/init.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mfd/ls6000se.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+
+#define SE_SDF_BUFSIZE (PAGE_SIZE * 2)
+
+struct sdf_dev {
+ struct miscdevice miscdev;
+ struct lsse_ch *se_ch;
+ struct completion sdf_completion;
+};
+
+struct sdf_msg {
+ u32 cmd;
+ u32 data_off;
+ u32 data_len;
+ u32 pad[5];
+};
+
+static void sdf_complete(struct lsse_ch *ch)
+{
+ struct sdf_dev *sdf = ch->priv;
+
+ complete(&sdf->sdf_completion);
+}
+
+static int send_sdf_cmd(struct sdf_dev *sdf, int len)
+{
+ struct sdf_msg *smsg = sdf->se_ch->smsg;
+
+ smsg->data_len = len;
+
+ return se_send_ch_requeset(sdf->se_ch);
+}
+
+static ssize_t sdf_read(struct file *file, char __user *buf,
+ size_t cnt, loff_t *offt)
+{
+ struct sdf_dev *sdf = container_of(file->private_data,
+ struct sdf_dev, miscdev);
+ struct sdf_msg *rmsg;
+
+ if (!wait_for_completion_timeout(&sdf->sdf_completion, HZ*5))
+ return -ETIME;
+
+ rmsg = (struct sdf_msg *)sdf->se_ch->rmsg;
+ if (copy_to_user(buf,
+ sdf->se_ch->data_buffer + rmsg->data_off, rmsg->data_len))
+ return -EFAULT;
+
+ return rmsg->data_len;
+}
+
+static ssize_t sdf_write(struct file *file, const char __user *buf,
+ size_t cnt, loff_t *offt)
+{
+ struct sdf_dev *sdf = container_of(file->private_data,
+ struct sdf_dev, miscdev);
+ int ret;
+
+ if (copy_from_user(sdf->se_ch->data_buffer, buf, cnt))
+ return -EFAULT;
+
+ ret = send_sdf_cmd(sdf, cnt);
+
+ return ret ? -EFAULT : cnt;
+}
+
+static const struct file_operations sdf_fops = {
+ .owner = THIS_MODULE,
+ .write = sdf_write,
+ .read = sdf_read,
+};
+
+static int sdf_probe(struct platform_device *pdev)
+{
+ struct sdf_msg *smsg;
+ struct sdf_dev *sdf;
+ static int idx;
+
+ sdf = devm_kzalloc(&pdev->dev, sizeof(*sdf), GFP_KERNEL);
+ if (!sdf)
+ return -ENOMEM;
+ init_completion(&sdf->sdf_completion);
+
+ sdf->se_ch = se_init_ch(pdev->dev.parent, SE_CH_SDF, SE_SDF_BUFSIZE,
+ sizeof(struct sdf_msg) * 2, sdf, sdf_complete);
+ smsg = sdf->se_ch->smsg;
+ smsg->cmd = SE_CMD_SDF;
+ smsg->data_off = sdf->se_ch->off;
+ sdf->miscdev.minor = MISC_DYNAMIC_MINOR;
+ sdf->miscdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+ "lsse_sdf%d", idx++);
+ sdf->miscdev.fops = &sdf_fops;
+
+ return misc_register(&sdf->miscdev);
+}
+
+static struct platform_driver loongson_sdf_driver = {
+ .probe = sdf_probe,
+ .driver = {
+ .name = "ls6000se-sdf",
+ },
+};
+module_platform_driver(loongson_sdf_driver);
+
+MODULE_ALIAS("platform:ls6000se-sdf");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yinggang Gu <guyinggang@...ngson.cn>");
+MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@...ngson.cn>");
+MODULE_DESCRIPTION("Loongson Secure Device Function driver");
--
2.43.0
Powered by blists - more mailing lists