^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");