diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-01 12:04:12 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-10-01 12:04:12 -0700 |
| commit | b4918003cf54f99004c136c26f96b6df7ab49fac (patch) | |
| tree | fdc7c8984d255e9d23117886fb786c188f6e8a72 /drivers/crypto | |
| parent | 2d274536245b58a43753a23d84dfadc9df1df489 (diff) | |
| parent | b9d6cfe2ae699bbf230a6c8e0e32212b04bff661 (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/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/crypto/Makefile | 1 | ||||
| -rw-r--r-- | drivers/crypto/loongson/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/crypto/loongson/Makefile | 1 | ||||
| -rw-r--r-- | drivers/crypto/loongson/loongson-rng.c | 209 |
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"); |
