Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Random Number Generator driver for the Keystone SOC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Authors:	Sandeep Nair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *		Vitaly Andrianov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/hw_random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/timekeeping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define SA_CMD_STATUS_OFS			0x8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /* TRNG enable control in SA System module*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define SA_CMD_STATUS_REG_TRNG_ENABLE		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* TRNG start control in TRNG module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define TRNG_CNTL_REG_TRNG_ENABLE		BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* Data ready indicator in STATUS register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define TRNG_STATUS_REG_READY			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /* Data ready clear control in INTACK register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define TRNG_INTACK_REG_READY			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  * Number of samples taken to gather entropy during startup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  * If value is 0, the number of samples is 2^24 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)  * equals value times 2^8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define TRNG_DEF_STARTUP_CYCLES			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define TRNG_CNTL_REG_STARTUP_CYCLES_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * Minimum number of samples taken to regenerate entropy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  * If value is 0, the number of samples is 2^24 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * equals value times 2^6.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define TRNG_DEF_MIN_REFILL_CYCLES		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define TRNG_CFG_REG_MIN_REFILL_CYCLES_SHIFT	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  * Maximum number of samples taken to regenerate entropy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)  * If value is 0, the number of samples is 2^24 else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)  * equals value times 2^8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define TRNG_DEF_MAX_REFILL_CYCLES		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #define TRNG_CFG_REG_MAX_REFILL_CYCLES_SHIFT	16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /* Number of CLK input cycles between samples */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define TRNG_DEF_CLK_DIV_CYCLES			0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define TRNG_CFG_REG_SAMPLE_DIV_SHIFT		8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) /* Maximum retries to get rng data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define SA_MAX_RNG_DATA_RETRIES			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /* Delay between retries (in usecs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define SA_RNG_DATA_RETRY_DELAY			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) struct trng_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	u32	output_l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	u32	output_h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	u32	status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	u32	intmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	u32	intack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	u32	control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	u32	config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) struct ks_sa_rng {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct device	*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct hwrng	rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct clk	*clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	struct regmap	*regmap_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	struct trng_regs __iomem *reg_rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	u64 ready_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	unsigned int refill_delay_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static unsigned int cycles_to_ns(unsigned long clk_rate, unsigned int cycles)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return DIV_ROUND_UP_ULL((TRNG_DEF_CLK_DIV_CYCLES + 1) * 1000000000ull *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 				cycles, clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) static unsigned int startup_delay_ns(unsigned long clk_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (!TRNG_DEF_STARTUP_CYCLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return cycles_to_ns(clk_rate, BIT(24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return cycles_to_ns(clk_rate, 256 * TRNG_DEF_STARTUP_CYCLES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) static unsigned int refill_delay_ns(unsigned long clk_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (!TRNG_DEF_MAX_REFILL_CYCLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return cycles_to_ns(clk_rate, BIT(24));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return cycles_to_ns(clk_rate, 256 * TRNG_DEF_MAX_REFILL_CYCLES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int ks_sa_rng_init(struct hwrng *rng)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct device *dev = (struct device *)rng->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	unsigned long clk_rate = clk_get_rate(ks_sa_rng->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	/* Enable RNG module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			  SA_CMD_STATUS_REG_TRNG_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			  SA_CMD_STATUS_REG_TRNG_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	/* Configure RNG module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	writel(0, &ks_sa_rng->reg_rng->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	value = TRNG_DEF_STARTUP_CYCLES << TRNG_CNTL_REG_STARTUP_CYCLES_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	writel(value, &ks_sa_rng->reg_rng->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	value =	(TRNG_DEF_MIN_REFILL_CYCLES <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		 TRNG_CFG_REG_MIN_REFILL_CYCLES_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		(TRNG_DEF_MAX_REFILL_CYCLES <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		 TRNG_CFG_REG_MAX_REFILL_CYCLES_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		(TRNG_DEF_CLK_DIV_CYCLES <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		 TRNG_CFG_REG_SAMPLE_DIV_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	writel(value, &ks_sa_rng->reg_rng->config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* Disable all interrupts from TRNG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	writel(0, &ks_sa_rng->reg_rng->intmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	/* Enable RNG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	value = readl(&ks_sa_rng->reg_rng->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	value |= TRNG_CNTL_REG_TRNG_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	writel(value, &ks_sa_rng->reg_rng->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	ks_sa_rng->ready_ts = ktime_get_ns() +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			      startup_delay_ns(clk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void ks_sa_rng_cleanup(struct hwrng *rng)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct device *dev = (struct device *)rng->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	/* Disable RNG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	writel(0, &ks_sa_rng->reg_rng->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			  SA_CMD_STATUS_REG_TRNG_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static int ks_sa_rng_data_read(struct hwrng *rng, u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct device *dev = (struct device *)rng->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	/* Read random data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	data[0] = readl(&ks_sa_rng->reg_rng->output_l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	data[1] = readl(&ks_sa_rng->reg_rng->output_h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	writel(TRNG_INTACK_REG_READY, &ks_sa_rng->reg_rng->intack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	ks_sa_rng->ready_ts = ktime_get_ns() + ks_sa_rng->refill_delay_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	return sizeof(u32) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int ks_sa_rng_data_present(struct hwrng *rng, int wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct device *dev = (struct device *)rng->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	u64 now = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	u32	ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int	j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (wait && now < ks_sa_rng->ready_ts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		/* Max delay expected here is 81920000 ns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		unsigned long min_delay =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			DIV_ROUND_UP((u32)(ks_sa_rng->ready_ts - now), 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		usleep_range(min_delay, min_delay + SA_RNG_DATA_RETRY_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	for (j = 0; j < SA_MAX_RNG_DATA_RETRIES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		ready = readl(&ks_sa_rng->reg_rng->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		ready &= TRNG_STATUS_REG_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		if (ready || !wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		udelay(SA_RNG_DATA_RETRY_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	return ready;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static int ks_sa_rng_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	struct ks_sa_rng	*ks_sa_rng;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	struct device		*dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	int			ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	ks_sa_rng = devm_kzalloc(dev, sizeof(*ks_sa_rng), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	if (!ks_sa_rng)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ks_sa_rng->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	ks_sa_rng->rng = (struct hwrng) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		.name = "ks_sa_hwrng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		.init = ks_sa_rng_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		.data_read = ks_sa_rng_data_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		.data_present = ks_sa_rng_data_present,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		.cleanup = ks_sa_rng_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	ks_sa_rng->rng.priv = (unsigned long)dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	ks_sa_rng->reg_rng = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	if (IS_ERR(ks_sa_rng->reg_rng))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		return PTR_ERR(ks_sa_rng->reg_rng);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	ks_sa_rng->regmap_cfg =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		syscon_regmap_lookup_by_phandle(dev->of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 						"ti,syscon-sa-cfg");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (IS_ERR(ks_sa_rng->regmap_cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		dev_err(dev, "syscon_node_to_regmap failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	ret = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		dev_err(dev, "Failed to enable SA power-domain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		pm_runtime_put_noidle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	platform_set_drvdata(pdev, ks_sa_rng);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	return devm_hwrng_register(&pdev->dev, &ks_sa_rng->rng);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int ks_sa_rng_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	pm_runtime_put_sync(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static const struct of_device_id ks_sa_rng_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		.compatible = "ti,keystone-rng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) MODULE_DEVICE_TABLE(of, ks_sa_rng_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static struct platform_driver ks_sa_rng_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		.name	= "ks-sa-rng",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		.of_match_table = ks_sa_rng_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	.probe		= ks_sa_rng_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	.remove		= ks_sa_rng_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) module_platform_driver(ks_sa_rng_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) MODULE_DESCRIPTION("Keystone NETCP SA H/W Random Number Generator driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) MODULE_AUTHOR("Vitaly Andrianov <vitalya@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) MODULE_LICENSE("GPL");