summaryrefslogtreecommitdiff
path: root/drivers/crypto
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2025-10-01 12:04:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2025-10-01 12:04:12 -0700
commitb4918003cf54f99004c136c26f96b6df7ab49fac (patch)
treefdc7c8984d255e9d23117886fb786c188f6e8a72 /drivers/crypto
parent2d274536245b58a43753a23d84dfadc9df1df489 (diff)
parentb9d6cfe2ae699bbf230a6c8e0e32212b04bff661 (diff)
Merge tag 'mfd-next-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones: "This round of updates contains a fair amount of new device support, a couple of fixes and some refactoring. The most notable additions include new drivers for Loongson's Security Engine, RNG and TPM, new drivers for TI's TPS6594 Power Button and BQ257xx Charger ICs. The rest of the set provides a return value check fix and a refactoring to use a more modern GPIO API for the VEXPRESS sysreg driver, the removal of a deprecated IRQ ACK function from the MC13xxx RTC driver and a new DT binding for the aforementioned TI BQ257xx charger. New Support & Features: - Add a suite of drivers for the Loongson Security Engine, including the core controller, a Random Number Generator (RNG) and Trusted Platform Module (TPM) support. - Introduce support for the TI TPS6594 PMIC's power button, including the input driver, MFD cell registration, and a system power-off handler. - Add comprehensive support for the TI BQ257xx series of charger ICs, including the core MFD driver and a power supply driver for the charger functionality. Improvements & Fixes: - Check the return value of devm_gpiochip_add_data() in the VEXPRESS sysreg driver to prevent potential silent failures. Cleanups & Refactoring: - Add a MAINTAINERS entry for the new Loongson Security Engine drivers. - Convert the VEXPRESS sysreg driver to use the modern generic GPIO chip API. Removals: - Remove the deprecated and unused mc13xxx_irq_ack() function from the MC13xxx RTC, input and touchscreen drivers. Device Tree Bindings Updates: - Add device tree bindings for the TI BQ25703A charger" * tag 'mfd-next-6.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (69 commits) mfd: simple-mfd-i2c: Add compatible string for LX2160ARDB mfd: simple-mfd-i2c: Keep compatible strings in alphabetical order dt-bindings: mfd: twl: Add missing sub-nodes for TWL4030 & TWL603x dt-bindings: watchdog: Add SMARC-sAM67 support dt-bindings: mfd: tps6594: Allow gpio-line-names mfd: intel-lpss: Add Intel Wildcat Lake LPSS PCI IDs mfd: 88pm886: Add GPADC cell mfd: vexpress-sysreg: Use more common syntax for compound literals mfd: rz-mtu3: Fix MTU5 NFCR register offset mfd: max77705: Setup the core driver as an interrupt controller mfd: cs42l43: Remove IRQ masking in suspend mfd: cs42l43: Move IRQ enable/disable to encompass force suspend mfd: ls2kbmc: Add Loongson-2K BMC reset function support mfd: ls2kbmc: Introduce Loongson-2K BMC core driver mfd: bd71828, bd71815: Prepare for power-supply support dt-bindings: mfd: aspeed: Add AST2700 SCU compatibles dt-bindings: mfd: Convert aspeed,ast2400-p2a-ctrl to DT schema dt-bindings: mfd: fsl,mc13xxx: Add buttons node dt-bindings: mfd: fsl,mc13xxx: Convert txt to DT schema mfd: macsmc: Add "apple,t8103-smc" compatible ...
Diffstat (limited to 'drivers/crypto')
-rw-r--r--drivers/crypto/Kconfig1
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/loongson/Kconfig5
-rw-r--r--drivers/crypto/loongson/Makefile1
-rw-r--r--drivers/crypto/loongson/loongson-rng.c209
5 files changed, 217 insertions, 0 deletions
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 04b4c43b6bae..c7a1060ba57a 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -840,6 +840,7 @@ config CRYPTO_DEV_CCREE
If unsure say Y.
source "drivers/crypto/hisilicon/Kconfig"
+source "drivers/crypto/loongson/Kconfig"
source "drivers/crypto/amlogic/Kconfig"
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 22eadcc8f4a2..125b99b24af1 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -44,6 +44,7 @@ obj-y += inside-secure/
obj-$(CONFIG_CRYPTO_DEV_ARTPEC6) += axis/
obj-y += xilinx/
obj-y += hisilicon/
+obj-y += loongson/
obj-$(CONFIG_CRYPTO_DEV_AMLOGIC_GXL) += amlogic/
obj-y += intel/
obj-y += starfive/
diff --git a/drivers/crypto/loongson/Kconfig b/drivers/crypto/loongson/Kconfig
new file mode 100644
index 000000000000..15475da8fc11
--- /dev/null
+++ b/drivers/crypto/loongson/Kconfig
@@ -0,0 +1,5 @@
+config CRYPTO_DEV_LOONGSON_RNG
+ tristate "Support for Loongson RNG Driver"
+ depends on MFD_LOONGSON_SE
+ help
+ Support for Loongson RNG Driver.
diff --git a/drivers/crypto/loongson/Makefile b/drivers/crypto/loongson/Makefile
new file mode 100644
index 000000000000..1ce5ec32b553
--- /dev/null
+++ b/drivers/crypto/loongson/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_CRYPTO_DEV_LOONGSON_RNG) += loongson-rng.o
diff --git a/drivers/crypto/loongson/loongson-rng.c b/drivers/crypto/loongson/loongson-rng.c
new file mode 100644
index 000000000000..3a4940260f9e
--- /dev/null
+++ b/drivers/crypto/loongson/loongson-rng.c
@@ -0,0 +1,209 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019 HiSilicon Limited. */
+/* Copyright (c) 2025 Loongson Technology Corporation Limited. */
+
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mfd/loongson-se.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <crypto/internal/rng.h>
+
+#define SE_SEED_SIZE 32
+
+struct loongson_rng_list {
+ struct mutex lock;
+ struct list_head list;
+ int registered;
+};
+
+struct loongson_rng {
+ u32 used;
+ struct loongson_se_engine *engine;
+ struct list_head list;
+ struct mutex lock;
+};
+
+struct loongson_rng_ctx {
+ struct loongson_rng *rng;
+};
+
+struct loongson_rng_cmd {
+ u32 cmd_id;
+ union {
+ u32 len;
+ u32 ret;
+ } u;
+ u32 seed_off;
+ u32 out_off;
+ u32 pad[4];
+};
+
+static struct loongson_rng_list rng_devices = {
+ .lock = __MUTEX_INITIALIZER(rng_devices.lock),
+ .list = LIST_HEAD_INIT(rng_devices.list),
+};
+
+static int loongson_rng_generate(struct crypto_rng *tfm, const u8 *src,
+ unsigned int slen, u8 *dstn, unsigned int dlen)
+{
+ struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm);
+ struct loongson_rng *rng = ctx->rng;
+ struct loongson_rng_cmd *cmd = rng->engine->command;
+ int err, len;
+
+ mutex_lock(&rng->lock);
+ cmd->seed_off = 0;
+ do {
+ len = min(dlen, rng->engine->buffer_size);
+ cmd = rng->engine->command;
+ cmd->u.len = len;
+ err = loongson_se_send_engine_cmd(rng->engine);
+ if (err)
+ break;
+
+ cmd = rng->engine->command_ret;
+ if (cmd->u.ret) {
+ err = -EIO;
+ break;
+ }
+
+ memcpy(dstn, rng->engine->data_buffer, len);
+ dlen -= len;
+ dstn += len;
+ } while (dlen > 0);
+ mutex_unlock(&rng->lock);
+
+ return err;
+}
+
+static int loongson_rng_init(struct crypto_tfm *tfm)
+{
+ struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm);
+ struct loongson_rng *rng;
+ u32 min_used = U32_MAX;
+
+ mutex_lock(&rng_devices.lock);
+ list_for_each_entry(rng, &rng_devices.list, list) {
+ if (rng->used < min_used) {
+ ctx->rng = rng;
+ min_used = rng->used;
+ }
+ }
+ ctx->rng->used++;
+ mutex_unlock(&rng_devices.lock);
+
+ return 0;
+}
+
+static void loongson_rng_exit(struct crypto_tfm *tfm)
+{
+ struct loongson_rng_ctx *ctx = crypto_tfm_ctx(tfm);
+
+ mutex_lock(&rng_devices.lock);
+ ctx->rng->used--;
+ mutex_unlock(&rng_devices.lock);
+}
+
+static int loongson_rng_seed(struct crypto_rng *tfm, const u8 *seed,
+ unsigned int slen)
+{
+ struct loongson_rng_ctx *ctx = crypto_rng_ctx(tfm);
+ struct loongson_rng *rng = ctx->rng;
+ struct loongson_rng_cmd *cmd;
+ int err;
+
+ if (slen < SE_SEED_SIZE)
+ return -EINVAL;
+
+ slen = min(slen, rng->engine->buffer_size);
+
+ mutex_lock(&rng->lock);
+ cmd = rng->engine->command;
+ cmd->u.len = slen;
+ cmd->seed_off = rng->engine->buffer_off;
+ memcpy(rng->engine->data_buffer, seed, slen);
+ err = loongson_se_send_engine_cmd(rng->engine);
+ if (err)
+ goto out;
+
+ cmd = rng->engine->command_ret;
+ if (cmd->u.ret)
+ err = -EIO;
+out:
+ mutex_unlock(&rng->lock);
+
+ return err;
+}
+
+static struct rng_alg loongson_rng_alg = {
+ .generate = loongson_rng_generate,
+ .seed = loongson_rng_seed,
+ .seedsize = SE_SEED_SIZE,
+ .base = {
+ .cra_name = "stdrng",
+ .cra_driver_name = "loongson_stdrng",
+ .cra_priority = 300,
+ .cra_ctxsize = sizeof(struct loongson_rng_ctx),
+ .cra_module = THIS_MODULE,
+ .cra_init = loongson_rng_init,
+ .cra_exit = loongson_rng_exit,
+ },
+};
+
+static int loongson_rng_probe(struct platform_device *pdev)
+{
+ struct loongson_rng_cmd *cmd;
+ struct loongson_rng *rng;
+ int ret = 0;
+
+ rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
+ if (!rng)
+ return -ENOMEM;
+
+ rng->engine = loongson_se_init_engine(pdev->dev.parent, SE_ENGINE_RNG);
+ if (!rng->engine)
+ return -ENODEV;
+ cmd = rng->engine->command;
+ cmd->cmd_id = SE_CMD_RNG;
+ cmd->out_off = rng->engine->buffer_off;
+ mutex_init(&rng->lock);
+
+ mutex_lock(&rng_devices.lock);
+
+ if (!rng_devices.registered) {
+ ret = crypto_register_rng(&loongson_rng_alg);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register crypto(%d)\n", ret);
+ goto out;
+ }
+ rng_devices.registered = 1;
+ }
+
+ list_add_tail(&rng->list, &rng_devices.list);
+out:
+ mutex_unlock(&rng_devices.lock);
+
+ return ret;
+}
+
+static struct platform_driver loongson_rng_driver = {
+ .probe = loongson_rng_probe,
+ .driver = {
+ .name = "loongson-rng",
+ },
+};
+module_platform_driver(loongson_rng_driver);
+
+MODULE_ALIAS("platform:loongson-rng");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yinggang Gu <guyinggang@loongson.cn>");
+MODULE_AUTHOR("Qunqin Zhao <zhaoqunqin@loongson.cn>");
+MODULE_DESCRIPTION("Loongson Random Number Generator driver");