linux/drivers/char/hw_random/stm32-rng.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2015, Daniel Thompson
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>

#define RNG_CR
#define RNG_CR_RNGEN
#define RNG_CR_CED
#define RNG_CR_CONFIG1
#define RNG_CR_NISTC
#define RNG_CR_CONFIG2
#define RNG_CR_CLKDIV_SHIFT
#define RNG_CR_CLKDIV
#define RNG_CR_CONFIG3
#define RNG_CR_CONDRST
#define RNG_CR_CONFLOCK
#define RNG_CR_ENTROPY_SRC_MASK
#define RNG_CR_CONFIG_MASK

#define RNG_SR
#define RNG_SR_DRDY
#define RNG_SR_CECS
#define RNG_SR_SECS
#define RNG_SR_CEIS
#define RNG_SR_SEIS

#define RNG_DR

#define RNG_NSCR
#define RNG_NSCR_MASK

#define RNG_HTCR

#define RNG_NB_RECOVER_TRIES

struct stm32_rng_data {};

/**
 * struct stm32_rng_config - RNG configuration data
 *
 * @cr:			RNG configuration. 0 means default hardware RNG configuration
 * @nscr:		Noise sources control configuration.
 * @htcr:		Health tests configuration.
 */
struct stm32_rng_config {};

struct stm32_rng_private {};

/*
 * Extracts from the STM32 RNG specification when RNG supports CONDRST.
 *
 * When a noise source (or seed) error occurs, the RNG stops generating
 * random numbers and sets to “1” both SEIS and SECS bits to indicate
 * that a seed error occurred. (...)
 *
 * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
 * description for details). This step is needed only if SECS is set.
 * Indeed, when SEIS is set and SECS is cleared it means RNG performed
 * the reset automatically (auto-reset).
 * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
 * to be cleared in the RNG_CR register, then confirm that SEIS is
 * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
 * the RNG_SR register.
 * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
 * cleared by RNG. The random number generation is now back to normal.
 */
static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_private *priv)
{}

/*
 * Extracts from the STM32 RNG specification, when CONDRST is not supported
 *
 * When a noise source (or seed) error occurs, the RNG stops generating
 * random numbers and sets to “1” both SEIS and SECS bits to indicate
 * that a seed error occurred. (...)
 *
 * The following sequence shall be used to fully recover from a seed
 * error after the RNG initialization:
 * 1. Clear the SEIS bit by writing it to “0”.
 * 2. Read out 12 words from the RNG_DR register, and discard each of
 * them in order to clean the pipeline.
 * 3. Confirm that SEIS is still cleared. Random number generation is
 * back to normal.
 */
static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_private *priv)
{}

static int stm32_rng_conceal_seed_error(struct hwrng *rng)
{
	struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng);

	dev_dbg(priv->dev, "Concealing seed error\n");

	if (priv->data->has_cond_reset)
		return stm32_rng_conceal_seed_error_cond_reset(priv);
	else
		return stm32_rng_conceal_seed_error_sw_reset(priv);
};


static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{}

static uint stm32_rng_clock_freq_restrain(struct hwrng *rng)
{}

static int stm32_rng_init(struct hwrng *rng)
{}

static void stm32_rng_remove(struct platform_device *ofdev)
{}

static int __maybe_unused stm32_rng_runtime_suspend(struct device *dev)
{}

static int __maybe_unused stm32_rng_suspend(struct device *dev)
{}

static int __maybe_unused stm32_rng_runtime_resume(struct device *dev)
{}

static int __maybe_unused stm32_rng_resume(struct device *dev)
{}

static const struct dev_pm_ops __maybe_unused stm32_rng_pm_ops =;

static const struct stm32_rng_data stm32mp13_rng_data =;

static const struct stm32_rng_data stm32_rng_data =;

static const struct of_device_id stm32_rng_match[] =;
MODULE_DEVICE_TABLE(of, stm32_rng_match);

static int stm32_rng_probe(struct platform_device *ofdev)
{}

static struct platform_driver stm32_rng_driver =;

module_platform_driver();

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();