11.11Smrg/*	$NetBSD: rk_v1crypto.c,v 1.11 2023/04/24 05:16:01 mrg Exp $	*/
21.1Sriastrad
31.1Sriastrad/*-
41.1Sriastrad * Copyright (c) 2020 The NetBSD Foundation, Inc.
51.1Sriastrad * All rights reserved.
61.1Sriastrad *
71.1Sriastrad * This code is derived from software contributed to The NetBSD Foundation
81.1Sriastrad * by Taylor R. Campbell.
91.1Sriastrad *
101.1Sriastrad * Redistribution and use in source and binary forms, with or without
111.1Sriastrad * modification, are permitted provided that the following conditions
121.1Sriastrad * are met:
131.1Sriastrad * 1. Redistributions of source code must retain the above copyright
141.1Sriastrad *    notice, this list of conditions and the following disclaimer.
151.1Sriastrad * 2. Redistributions in binary form must reproduce the above copyright
161.1Sriastrad *    notice, this list of conditions and the following disclaimer in the
171.1Sriastrad *    documentation and/or other materials provided with the distribution.
181.1Sriastrad *
191.1Sriastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201.1Sriastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211.1Sriastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221.1Sriastrad * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231.1Sriastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241.1Sriastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251.1Sriastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261.1Sriastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271.1Sriastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281.1Sriastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291.1Sriastrad * POSSIBILITY OF SUCH DAMAGE.
301.1Sriastrad */
311.1Sriastrad
321.1Sriastrad/*
331.1Sriastrad * rk_v1crypto -- Rockchip crypto v1 driver
341.1Sriastrad *
351.1Sriastrad * This is just the RNG for now.
361.1Sriastrad */
371.1Sriastrad
381.1Sriastrad#include <sys/cdefs.h>
391.11Smrg__KERNEL_RCSID(1, "$NetBSD: rk_v1crypto.c,v 1.11 2023/04/24 05:16:01 mrg Exp $");
401.1Sriastrad
411.1Sriastrad#include <sys/types.h>
421.1Sriastrad
431.1Sriastrad#include <sys/bus.h>
441.1Sriastrad#include <sys/device.h>
451.1Sriastrad#include <sys/errno.h>
461.1Sriastrad#include <sys/mutex.h>
471.1Sriastrad#include <sys/rndsource.h>
481.1Sriastrad#include <sys/sysctl.h>
491.1Sriastrad
501.1Sriastrad#include <dev/fdt/fdtvar.h>
511.1Sriastrad
521.1Sriastrad#include <arm/rockchip/rk_v1crypto.h>
531.1Sriastrad
541.1Sriastradstruct rk_v1crypto_softc {
551.1Sriastrad	device_t			sc_dev;
561.1Sriastrad	bus_space_tag_t			sc_bst;
571.1Sriastrad	bus_space_handle_t		sc_bsh;
581.1Sriastrad	kmutex_t			sc_lock;
591.1Sriastrad	struct krndsource		sc_rndsource;
601.1Sriastrad	struct rk_v1crypto_sysctl {
611.1Sriastrad		struct sysctllog		*cy_log;
621.1Sriastrad		const struct sysctlnode		*cy_root_node;
631.1Sriastrad	}				sc_sysctl;
641.1Sriastrad};
651.1Sriastrad
661.1Sriastradstatic int rk_v1crypto_match(device_t, cfdata_t, void *);
671.1Sriastradstatic void rk_v1crypto_attach(device_t, device_t, void *);
681.1Sriastradstatic int rk_v1crypto_selftest(struct rk_v1crypto_softc *);
691.1Sriastradstatic void rk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *);
701.1Sriastradstatic void rk_v1crypto_rng_get(size_t, void *);
711.1Sriastradstatic void rk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *);
721.1Sriastradstatic int rk_v1crypto_sysctl_rng(SYSCTLFN_ARGS);
731.1Sriastradstatic int rk_v1crypto_rng(struct rk_v1crypto_softc *,
741.1Sriastrad    uint32_t[static RK_V1CRYPTO_TRNG_NOUT]);
751.1Sriastrad
761.1Sriastradstatic uint32_t
771.1SriastradRKC_READ(struct rk_v1crypto_softc *sc, bus_addr_t reg)
781.1Sriastrad{
791.1Sriastrad	return bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg);
801.1Sriastrad}
811.1Sriastrad
821.1Sriastradstatic void
831.1SriastradRKC_WRITE(struct rk_v1crypto_softc *sc, bus_addr_t reg, uint32_t v)
841.1Sriastrad{
851.3Stnn	bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, v);
861.1Sriastrad}
871.1Sriastrad
881.1Sriastradstatic inline void
891.1SriastradRKC_CTRL(struct rk_v1crypto_softc *sc, uint16_t m, uint16_t v)
901.1Sriastrad{
911.1Sriastrad	uint32_t c = 0;
921.1Sriastrad
931.1Sriastrad	c |= __SHIFTIN(m, RK_V1CRYPTO_CTRL_MASK);
941.1Sriastrad	c |= __SHIFTIN(v, m);
951.1Sriastrad	RKC_WRITE(sc, RK_V1CRYPTO_CTRL, c);
961.1Sriastrad}
971.1Sriastrad
981.1SriastradCFATTACH_DECL_NEW(rk_v1crypto, sizeof(struct rk_v1crypto_softc),
991.1Sriastrad    rk_v1crypto_match, rk_v1crypto_attach, NULL, NULL);
1001.1Sriastrad
1011.11Smrgstruct rk_v1crypto_data {
1021.11Smrg	int num_clks;
1031.11Smrg	const char *const clks[];
1041.11Smrg};
1051.11Smrg
1061.11Smrgstatic const struct rk_v1crypto_data rk3288_crypto_data = {
1071.11Smrg	.num_clks = 4,
1081.11Smrg	.clks = {"aclk", "hclk", "sclk", "apb_pclk"},
1091.11Smrg};
1101.11Smrg
1111.11Smrgstatic const struct rk_v1crypto_data rk3328_crypto_data = {
1121.11Smrg	.num_clks = 3,
1131.11Smrg	.clks = {"hclk_master", "hclk_slave", "sclk"},
1141.11Smrg};
1151.11Smrg
1161.4Sthorpejstatic const struct device_compatible_entry compat_data[] = {
1171.11Smrg	{ .compat = "rockchip,rk3288-crypto", .data = &rk3288_crypto_data },
1181.11Smrg	{ .compat = "rockchip,rk3328-crypto", .data = &rk3328_crypto_data },
1191.6Sthorpej	DEVICE_COMPAT_EOL
1201.1Sriastrad};
1211.1Sriastrad
1221.1Sriastradstatic int
1231.1Sriastradrk_v1crypto_match(device_t parent, cfdata_t cf, void *aux)
1241.1Sriastrad{
1251.1Sriastrad	const struct fdt_attach_args *const faa = aux;
1261.1Sriastrad
1271.7Sthorpej	return of_compatible_match(faa->faa_phandle, compat_data);
1281.1Sriastrad}
1291.1Sriastrad
1301.1Sriastradstatic void
1311.1Sriastradrk_v1crypto_attach(device_t parent, device_t self, void *aux)
1321.1Sriastrad{
1331.1Sriastrad	struct rk_v1crypto_softc *const sc = device_private(self);
1341.1Sriastrad	const struct fdt_attach_args *const faa = aux;
1351.1Sriastrad	bus_addr_t addr;
1361.1Sriastrad	bus_size_t size;
1371.1Sriastrad	const int phandle = faa->faa_phandle;
1381.1Sriastrad	struct fdtbus_reset *rst;
1391.1Sriastrad	unsigned i;
1401.1Sriastrad	uint32_t ctrl;
1411.11Smrg	const struct rk_v1crypto_data *config =
1421.11Smrg	    of_compatible_lookup(phandle, compat_data)->data;
1431.11Smrg	const char *const *clks = config->clks;
1441.1Sriastrad
1451.1Sriastrad	fdtbus_clock_assign(phandle);
1461.1Sriastrad
1471.1Sriastrad	sc->sc_dev = self;
1481.1Sriastrad	sc->sc_bst = faa->faa_bst;
1491.8Sriastrad	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTSERIAL);
1501.1Sriastrad
1511.1Sriastrad	/* Get and map device registers.  */
1521.1Sriastrad	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
1531.1Sriastrad		aprint_error(": couldn't get registers\n");
1541.1Sriastrad		return;
1551.1Sriastrad	}
1561.1Sriastrad	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
1571.1Sriastrad		aprint_error(": couldn't map registers\n");
1581.1Sriastrad		return;
1591.1Sriastrad	}
1601.1Sriastrad
1611.1Sriastrad	/* Enable the clocks.  */
1621.11Smrg	for (i = 0; i < config->num_clks; i++) {
1631.1Sriastrad		if (fdtbus_clock_enable(phandle, clks[i], true) != 0) {
1641.1Sriastrad			aprint_error(": couldn't enable %s clock\n", clks[i]);
1651.1Sriastrad			return;
1661.1Sriastrad		}
1671.1Sriastrad	}
1681.1Sriastrad
1691.1Sriastrad	/* Get a reset handle if we need and try to deassert it.  */
1701.1Sriastrad	if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) {
1711.1Sriastrad		if (fdtbus_reset_deassert(rst) != 0) {
1721.1Sriastrad			aprint_error(": couldn't de-assert reset\n");
1731.1Sriastrad			return;
1741.1Sriastrad		}
1751.1Sriastrad	}
1761.1Sriastrad
1771.1Sriastrad	aprint_naive("\n");
1781.1Sriastrad	aprint_normal(": Crypto v1\n");
1791.1Sriastrad
1801.1Sriastrad	/*
1811.1Sriastrad	 * Enable ring oscillator to start gathering entropy, and set
1821.1Sriastrad	 * up the crypto clock to sample it once every 100 cycles.
1831.1Sriastrad	 *
1841.1Sriastrad	 * The ring oscillator can run even when the clock is gated or
1851.1Sriastrad	 * flush is asserted, and the longer we run it, the less it
1861.1Sriastrad	 * will be synchronized with the main clock owing to jitter
1871.1Sriastrad	 * ideally from unpredictable thermal noise.
1881.1Sriastrad	 */
1891.1Sriastrad	ctrl = RK_V1CRYPTO_TRNG_CTRL_OSC_ENABLE;
1901.1Sriastrad	ctrl |= __SHIFTIN(100, RK_V1CRYPTO_TRNG_CTRL_CYCLES);
1911.1Sriastrad	RKC_WRITE(sc, RK_V1CRYPTO_TRNG_CTRL, ctrl);
1921.1Sriastrad
1931.1Sriastrad	if (rk_v1crypto_selftest(sc))
1941.1Sriastrad		return;
1951.1Sriastrad	rk_v1crypto_rndsource_attach(sc);
1961.1Sriastrad	rk_v1crypto_sysctl_attach(sc);
1971.1Sriastrad}
1981.1Sriastrad
1991.1Sriastradstatic int
2001.1Sriastradrk_v1crypto_selftest(struct rk_v1crypto_softc *sc)
2011.1Sriastrad{
2021.1Sriastrad	static const uint32_t key[4] = {0};
2031.1Sriastrad	static const uint32_t input[4] = {0};
2041.1Sriastrad	static const uint32_t expected[4] = {
2051.1Sriastrad		0x66e94bd4, 0xef8a2c3b, 0x884cfa59, 0xca342b2e,
2061.1Sriastrad	};
2071.1Sriastrad	uint32_t output[4];
2081.1Sriastrad	uint32_t ctrl;
2091.1Sriastrad	unsigned i, timo;
2101.1Sriastrad
2111.1Sriastrad	/* Program the key and input block.  */
2121.1Sriastrad	for (i = 0; i < 4; i++)
2131.1Sriastrad		RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), key[i]);
2141.1Sriastrad	for (i = 0; i < 4; i++)
2151.1Sriastrad		RKC_WRITE(sc, RK_V1CRYPTO_AES_DIN(i), input[i]);
2161.1Sriastrad
2171.1Sriastrad	/*
2181.1Sriastrad	 * Set up the AES unit to do AES-128 `ECB' (i.e., just the raw
2191.1Sriastrad	 * AES permutation) in the encryption direction.
2201.1Sriastrad	 */
2211.1Sriastrad	ctrl = 0;
2221.1Sriastrad	ctrl |= RK_V1CRYPTO_AES_CTRL_KEYCHANGE;
2231.1Sriastrad	ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_MODE_ECB,
2241.1Sriastrad	    RK_V1CRYPTO_AES_CTRL_MODE);
2251.1Sriastrad	ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_KEYSIZE_128,
2261.1Sriastrad	    RK_V1CRYPTO_AES_CTRL_KEYSIZE);
2271.1Sriastrad	ctrl |= __SHIFTIN(RK_V1CRYPTO_AES_CTRL_DIR_ENC,
2281.1Sriastrad	    RK_V1CRYPTO_AES_CTRL_DIR);
2291.1Sriastrad	RKC_WRITE(sc, RK_V1CRYPTO_AES_CTRL, ctrl);
2301.1Sriastrad
2311.1Sriastrad	/* Kick it off.  */
2321.1Sriastrad	RKC_CTRL(sc, RK_V1CRYPTO_CTRL_AES_START, 1);
2331.1Sriastrad
2341.1Sriastrad	/* Wait up to 1ms for it to complete.  */
2351.1Sriastrad	timo = 1000;
2361.1Sriastrad	while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_AES_START) {
2371.1Sriastrad		if (--timo == 0) {
2381.1Sriastrad			device_printf(sc->sc_dev, "AES self-test timed out\n");
2391.1Sriastrad			return -1;
2401.1Sriastrad		}
2411.1Sriastrad		DELAY(1);
2421.1Sriastrad	}
2431.1Sriastrad
2441.1Sriastrad	/* Read the output.  */
2451.1Sriastrad	for (i = 0; i < 4; i++)
2461.1Sriastrad		output[i] = RKC_READ(sc, RK_V1CRYPTO_AES_DOUT(i));
2471.1Sriastrad
2481.1Sriastrad	/* Verify the output.  */
2491.1Sriastrad	for (i = 0; i < 4; i++) {
2501.1Sriastrad		if (output[i] != expected[i]) {
2511.1Sriastrad			device_printf(sc->sc_dev, "AES self-test failed\n");
2521.1Sriastrad			return -1;
2531.1Sriastrad		}
2541.1Sriastrad	}
2551.1Sriastrad
2561.1Sriastrad	/* Success!  */
2571.1Sriastrad	return 0;
2581.1Sriastrad}
2591.1Sriastrad
2601.1Sriastradstatic void
2611.1Sriastradrk_v1crypto_rndsource_attach(struct rk_v1crypto_softc *sc)
2621.1Sriastrad{
2631.1Sriastrad	device_t self = sc->sc_dev;
2641.1Sriastrad
2651.1Sriastrad	rndsource_setcb(&sc->sc_rndsource, rk_v1crypto_rng_get, sc);
2661.1Sriastrad	rnd_attach_source(&sc->sc_rndsource, device_xname(self),
2671.1Sriastrad	    RND_TYPE_RNG, RND_FLAG_DEFAULT|RND_FLAG_HASCB);
2681.1Sriastrad}
2691.1Sriastrad
2701.1Sriastradstatic void
2711.1Sriastradrk_v1crypto_rng_get(size_t nbytes, void *cookie)
2721.1Sriastrad{
2731.1Sriastrad	struct rk_v1crypto_softc *sc = cookie;
2741.1Sriastrad	device_t self = sc->sc_dev;
2751.1Sriastrad	uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
2761.1Sriastrad	uint32_t entropybits = NBBY*sizeof(buf)/2; /* be conservative */
2771.1Sriastrad	unsigned n = RK_V1CRYPTO_TRNG_NOUT;
2781.1Sriastrad	int error;
2791.1Sriastrad	size_t nbits = NBBY*nbytes;
2801.1Sriastrad
2811.1Sriastrad	while (nbits) {
2821.1Sriastrad		CTASSERT((RK_V1CRYPTO_TRNG_NOUT % 2) == 0);
2831.1Sriastrad
2841.1Sriastrad		error = rk_v1crypto_rng(sc, buf);
2851.1Sriastrad		if (error) {
2861.1Sriastrad			device_printf(self, "timed out\n");
2871.1Sriastrad			break;
2881.1Sriastrad		}
2891.10Sriastrad		if (consttime_memequal(buf, buf + n/2, sizeof(buf[0]) * n/2)) {
2901.1Sriastrad			device_printf(self, "failed repeated output test\n");
2911.1Sriastrad			break;
2921.1Sriastrad		}
2931.2Sriastrad		rnd_add_data_sync(&sc->sc_rndsource, buf, sizeof buf,
2941.2Sriastrad		    entropybits);
2951.1Sriastrad		nbits -= MIN(nbits, MAX(1, entropybits));
2961.1Sriastrad	}
2971.1Sriastrad	explicit_memset(buf, 0, sizeof buf);
2981.1Sriastrad}
2991.1Sriastrad
3001.1Sriastradstatic void
3011.1Sriastradrk_v1crypto_sysctl_attach(struct rk_v1crypto_softc *sc)
3021.1Sriastrad{
3031.1Sriastrad	device_t self = sc->sc_dev;
3041.1Sriastrad	struct rk_v1crypto_sysctl *cy = &sc->sc_sysctl;
3051.1Sriastrad	int error;
3061.1Sriastrad
3071.1Sriastrad	/* hw.rkv1cryptoN (node) */
3081.1Sriastrad	error = sysctl_createv(&cy->cy_log, 0, NULL, &cy->cy_root_node,
3091.1Sriastrad	    CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self),
3101.1Sriastrad	    SYSCTL_DESCR("rk crypto v1 engine knobs"),
3111.1Sriastrad	    NULL, 0, NULL, 0,
3121.1Sriastrad	    CTL_HW, CTL_CREATE, CTL_EOL);
3131.1Sriastrad	if (error) {
3141.1Sriastrad		aprint_error_dev(self,
3151.1Sriastrad		    "failed to set up sysctl hw.%s: %d\n",
3161.1Sriastrad		    device_xname(self), error);
3171.1Sriastrad		return;
3181.1Sriastrad	}
3191.1Sriastrad
3201.1Sriastrad	/* hw.rkv1cryptoN.rng (`struct', 32-byte array) */
3211.9Sriastrad	error = sysctl_createv(&cy->cy_log, 0, &cy->cy_root_node, NULL,
3221.1Sriastrad	    CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT,
3231.1Sriastrad	    "rng", SYSCTL_DESCR("Read up to 32 bytes out of the TRNG"),
3241.1Sriastrad	    &rk_v1crypto_sysctl_rng, 0, sc, 0, CTL_CREATE, CTL_EOL);
3251.1Sriastrad	if (error) {
3261.1Sriastrad		aprint_error_dev(self,
3271.1Sriastrad		    "failed to set up sysctl hw.%s.rng: %d\n",
3281.1Sriastrad		    device_xname(self), error);
3291.1Sriastrad		return;
3301.1Sriastrad	}
3311.1Sriastrad}
3321.1Sriastrad
3331.1Sriastradstatic int
3341.1Sriastradrk_v1crypto_sysctl_rng(SYSCTLFN_ARGS)
3351.1Sriastrad{
3361.1Sriastrad	uint32_t buf[RK_V1CRYPTO_TRNG_NOUT];
3371.1Sriastrad	struct sysctlnode node = *rnode;
3381.1Sriastrad	struct rk_v1crypto_softc *sc = node.sysctl_data;
3391.1Sriastrad	size_t size;
3401.1Sriastrad	int error;
3411.1Sriastrad
3421.1Sriastrad	/* If oldp == NULL, the caller wants to learn the size.  */
3431.1Sriastrad	if (oldp == NULL) {
3441.1Sriastrad		*oldlenp = sizeof buf;
3451.1Sriastrad		return 0;
3461.1Sriastrad	}
3471.1Sriastrad
3481.1Sriastrad	/* Verify the output buffer size is reasonable.  */
3491.1Sriastrad	size = *oldlenp;
3501.1Sriastrad	if (size > sizeof buf)	/* size_t, so never negative */
3511.1Sriastrad		return E2BIG;
3521.1Sriastrad	if (size == 0)
3531.1Sriastrad		return 0;	/* nothing to do */
3541.1Sriastrad
3551.1Sriastrad	/* Generate data.  */
3561.1Sriastrad	error = rk_v1crypto_rng(sc, buf);
3571.1Sriastrad	if (error)
3581.1Sriastrad		return error;
3591.1Sriastrad
3601.1Sriastrad	/* Copy out the data.  */
3611.1Sriastrad	node.sysctl_data = buf;
3621.1Sriastrad	node.sysctl_size = size;
3631.1Sriastrad	error = sysctl_lookup(SYSCTLFN_CALL(&node));
3641.1Sriastrad
3651.1Sriastrad	/* Clear the buffer.  */
3661.1Sriastrad	explicit_memset(buf, 0, sizeof buf);
3671.1Sriastrad
3681.1Sriastrad	/* Return the sysctl_lookup error, if any.  */
3691.1Sriastrad	return error;
3701.1Sriastrad}
3711.1Sriastrad
3721.1Sriastradstatic int
3731.1Sriastradrk_v1crypto_rng(struct rk_v1crypto_softc *sc,
3741.1Sriastrad    uint32_t buf[static RK_V1CRYPTO_TRNG_NOUT])
3751.1Sriastrad{
3761.1Sriastrad	unsigned i, timo;
3771.1Sriastrad	int error;
3781.1Sriastrad
3791.1Sriastrad	/* Acquire lock to serialize access to TRNG.  */
3801.1Sriastrad	mutex_enter(&sc->sc_lock);
3811.1Sriastrad
3821.1Sriastrad	/*
3831.1Sriastrad	 * Query TRNG and wait up to 1ms for it to post.  Empirically,
3841.1Sriastrad	 * this takes around 120us.
3851.1Sriastrad	 */
3861.1Sriastrad	RKC_CTRL(sc, RK_V1CRYPTO_CTRL_TRNG_START, 1);
3871.1Sriastrad	timo = 1000;
3881.1Sriastrad	while (RKC_READ(sc, RK_V1CRYPTO_CTRL) & RK_V1CRYPTO_CTRL_TRNG_START) {
3891.1Sriastrad		if (--timo == 0) {
3901.1Sriastrad			error = ETIMEDOUT;
3911.1Sriastrad			goto out;
3921.1Sriastrad		}
3931.1Sriastrad		DELAY(1);
3941.1Sriastrad	}
3951.1Sriastrad
3961.1Sriastrad	/* Read out the data.  */
3971.1Sriastrad	for (i = 0; i < RK_V1CRYPTO_TRNG_NOUT; i++)
3981.1Sriastrad		buf[i] = RKC_READ(sc, RK_V1CRYPTO_TRNG_DOUT(i));
3991.1Sriastrad
4001.1Sriastrad	/* Success!  */
4011.1Sriastrad	error = 0;
4021.1Sriastradout:	mutex_exit(&sc->sc_lock);
4031.1Sriastrad	return error;
4041.1Sriastrad}
405