-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
crypto: hisilicon/trng - add HiSilicon TRNG driver support
Move existing char/hw_random/hisi-trng-v2.c to crypto/hisilicon/trng.c. Signed-off-by: Weili Qian <qianweili@huawei.com> Reviewed-by: Zaibo Xu <xuzaibo@huawei.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
- Loading branch information
Weili Qian
authored and
Herbert Xu
committed
Nov 27, 2020
1 parent
4e0b858
commit 56c6da1
Showing
5 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
obj-$(CONFIG_CRYPTO_DEV_HISI_TRNG) += hisi-trng-v2.o | ||
hisi-trng-v2-objs = trng.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2019 HiSilicon Limited. */ | ||
|
||
#include <linux/acpi.h> | ||
#include <linux/err.h> | ||
#include <linux/hw_random.h> | ||
#include <linux/io.h> | ||
#include <linux/iopoll.h> | ||
#include <linux/kernel.h> | ||
#include <linux/module.h> | ||
#include <linux/platform_device.h> | ||
#include <linux/random.h> | ||
|
||
#define HISI_TRNG_REG 0x00F0 | ||
#define HISI_TRNG_BYTES 4 | ||
#define HISI_TRNG_QUALITY 512 | ||
#define SLEEP_US 10 | ||
#define TIMEOUT_US 10000 | ||
|
||
struct hisi_trng { | ||
void __iomem *base; | ||
struct hwrng rng; | ||
}; | ||
|
||
static int hisi_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) | ||
{ | ||
struct hisi_trng *trng; | ||
int currsize = 0; | ||
u32 val = 0; | ||
u32 ret; | ||
|
||
trng = container_of(rng, struct hisi_trng, rng); | ||
|
||
do { | ||
ret = readl_poll_timeout(trng->base + HISI_TRNG_REG, val, | ||
val, SLEEP_US, TIMEOUT_US); | ||
if (ret) | ||
return currsize; | ||
|
||
if (max - currsize >= HISI_TRNG_BYTES) { | ||
memcpy(buf + currsize, &val, HISI_TRNG_BYTES); | ||
currsize += HISI_TRNG_BYTES; | ||
if (currsize == max) | ||
return currsize; | ||
continue; | ||
} | ||
|
||
/* copy remaining bytes */ | ||
memcpy(buf + currsize, &val, max - currsize); | ||
currsize = max; | ||
} while (currsize < max); | ||
|
||
return currsize; | ||
} | ||
|
||
static int hisi_trng_probe(struct platform_device *pdev) | ||
{ | ||
struct hisi_trng *trng; | ||
int ret; | ||
|
||
trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); | ||
if (!trng) | ||
return -ENOMEM; | ||
|
||
trng->base = devm_platform_ioremap_resource(pdev, 0); | ||
if (IS_ERR(trng->base)) | ||
return PTR_ERR(trng->base); | ||
|
||
trng->rng.name = pdev->name; | ||
trng->rng.read = hisi_trng_read; | ||
trng->rng.quality = HISI_TRNG_QUALITY; | ||
|
||
ret = devm_hwrng_register(&pdev->dev, &trng->rng); | ||
if (ret) | ||
dev_err(&pdev->dev, "failed to register hwrng!\n"); | ||
|
||
return ret; | ||
} | ||
|
||
static const struct acpi_device_id hisi_trng_acpi_match[] = { | ||
{ "HISI02B3", 0 }, | ||
{ } | ||
}; | ||
MODULE_DEVICE_TABLE(acpi, hisi_trng_acpi_match); | ||
|
||
static struct platform_driver hisi_trng_driver = { | ||
.probe = hisi_trng_probe, | ||
.driver = { | ||
.name = "hisi-trng-v2", | ||
.acpi_match_table = ACPI_PTR(hisi_trng_acpi_match), | ||
}, | ||
}; | ||
|
||
module_platform_driver(hisi_trng_driver); | ||
|
||
MODULE_LICENSE("GPL v2"); | ||
MODULE_AUTHOR("Weili Qian <qianweili@huawei.com>"); | ||
MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com>"); | ||
MODULE_DESCRIPTION("HiSilicon true random number generator V2 driver"); |