summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2020-06-25 18:05:03 +0300
committerJani Nikula <jani.nikula@intel.com>2020-06-25 18:05:03 +0300
commit0f69403d2535ffc7200a8414cf3ca66a49b0d741 (patch)
tree3ce85dd08359ea872aa8fb9bd12072efdb80a787 /drivers/char
parent580fbdc5136822208f107500682e50a1cb232e94 (diff)
parent0a19b068acc47d05212f03e494381926dc0381e2 (diff)
Merge drm/drm-next into drm-intel-next-queued
Catch up with upstream, in particular to get c1e8d7c6a7a6 ("mmap locking API: convert mmap_sem comments"). Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig24
-rw-r--r--drivers/char/agp/Kconfig6
-rw-r--r--drivers/char/agp/frontend.c1
-rw-r--r--drivers/char/agp/generic.c1
-rw-r--r--drivers/char/bsr.c1
-rw-r--r--drivers/char/hw_random/Kconfig75
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/cctrng.c735
-rw-r--r--drivers/char/hw_random/cctrng.h72
-rw-r--r--drivers/char/hw_random/ks-sa-rng.c1
-rw-r--r--drivers/char/hw_random/omap-rng.c5
-rw-r--r--drivers/char/hw_random/optee-rng.c2
-rw-r--r--drivers/char/hw_random/virtio-rng.c1
-rw-r--r--drivers/char/hw_random/xgene-rng.c4
-rw-r--r--drivers/char/ipmi/Kconfig2
-rw-r--r--drivers/char/ipmi/bt-bmc.c21
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c9
-rw-r--r--drivers/char/ipmi/ipmi_si_hotmod.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c2
-rw-r--r--drivers/char/ipmi/ipmi_si_platform.c2
-rw-r--r--drivers/char/ipmi/ipmi_ssif.c24
-rw-r--r--drivers/char/mem.c103
-rw-r--r--drivers/char/mspec.c3
-rw-r--r--drivers/char/nvram.c4
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c14
-rw-r--r--drivers/char/random.c12
-rw-r--r--drivers/char/tlclk.c17
-rw-r--r--drivers/char/tpm/Kconfig30
-rw-r--r--drivers/char/tpm/eventlog/tpm2.c12
-rw-r--r--drivers/char/tpm/st33zp24/Kconfig6
-rw-r--r--drivers/char/tpm/tpm-interface.c2
-rw-r--r--drivers/char/tpm/tpm2-cmd.c1
-rw-r--r--drivers/char/tpm/tpm_ftpm_tee.c2
-rw-r--r--drivers/char/tpm/tpm_ibmvtpm.c136
-rw-r--r--drivers/char/tpm/tpm_tis_core.c8
-rw-r--r--drivers/char/virtio_console.c2
36 files changed, 1117 insertions, 226 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index d4665fe9ccd2..98c3a5d8003e 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -11,7 +11,7 @@ config TTY_PRINTK
tristate "TTY driver to output user messages via printk"
depends on EXPERT && TTY
default n
- ---help---
+ help
If you say Y here, the support for writing user messages (i.e.
console messages) via printk is available.
@@ -33,7 +33,7 @@ config TTY_PRINTK_LEVEL
config PRINTER
tristate "Parallel printer support"
depends on PARPORT
- ---help---
+ help
If you intend to attach a printer to the parallel port of your Linux
box (as opposed to using a serial printer; if the connector at the
printer has 9 or 25 holes ["female"], then it's serial), say Y.
@@ -59,7 +59,7 @@ config PRINTER
config LP_CONSOLE
bool "Support for console on line printer"
depends on PRINTER
- ---help---
+ help
If you want kernel messages to be printed out as they occur, you
can have a console on the printer. This option adds support for
doing that; to actually get it to happen you need to pass the
@@ -76,7 +76,7 @@ config LP_CONSOLE
config PPDEV
tristate "Support for user-space parallel port device drivers"
depends on PARPORT
- ---help---
+ help
Saying Y to this adds support for /dev/parport device nodes. This
is needed for programs that want portable access to the parallel
port, for instance deviceid (which displays Plug-and-Play device
@@ -146,7 +146,7 @@ config DS1620
config NWBUTTON
tristate "NetWinder Button"
depends on ARCH_NETWINDER
- ---help---
+ help
If you say Y here and create a character device node /dev/nwbutton
with major and minor numbers 10 and 158 ("man mknod"), then every
time the orange button is pressed a number of times, the number of
@@ -182,7 +182,7 @@ config NWBUTTON_REBOOT
config NWFLASH
tristate "NetWinder flash support"
depends on ARCH_NETWINDER
- ---help---
+ help
If you say Y here and create a character device /dev/flash with
major 10 and minor 160 you can manipulate the flash ROM containing
the NetWinder firmware. Be careful as accidentally overwriting the
@@ -209,7 +209,7 @@ config DTLK
config XILINX_HWICAP
tristate "Xilinx HWICAP Support"
- depends on XILINX_VIRTEX || MICROBLAZE
+ depends on MICROBLAZE
help
This option enables support for Xilinx Internal Configuration
Access Port (ICAP) driver. The ICAP is used on Xilinx Virtex
@@ -220,7 +220,7 @@ config XILINX_HWICAP
config R3964
tristate "Siemens R3964 line discipline"
depends on TTY && BROKEN
- ---help---
+ help
This driver allows synchronous communication with devices using the
Siemens R3964 packet protocol. Unless you are dealing with special
hardware like PLCs, you are unlikely to need this.
@@ -233,7 +233,7 @@ config R3964
config APPLICOM
tristate "Applicom intelligent fieldbus card support"
depends on PCI
- ---help---
+ help
This driver provides the kernel-side support for the intelligent
fieldbus cards made by Applicom International. More information
about these cards can be found on the WWW at the address
@@ -248,7 +248,7 @@ config APPLICOM
config SONYPI
tristate "Sony Vaio Programmable I/O Control Device support"
depends on X86_32 && PCI && INPUT
- ---help---
+ help
This driver enables access to the Sony Programmable I/O Control
Device which can be found in many (all ?) Sony Vaio laptops.
@@ -269,7 +269,7 @@ config MWAVE
tristate "ACP Modem (Mwave) support"
depends on X86 && TTY
select SERIAL_8250
- ---help---
+ help
The ACP modem (Mwave) for Linux is a WinModem. It is composed of a
kernel driver and a user level application. Together these components
support direct attachment to public switched telephone networks (PSTNs)
@@ -347,7 +347,7 @@ config NVRAM
tristate "/dev/nvram support"
depends on X86 || HAVE_ARCH_NVRAM_OPS
default M68K || PPC
- ---help---
+ help
If you say Y here and create a character special file /dev/nvram
with major number 10 and minor number 144 using mknod ("man mknod"),
you get read and write access to the non-volatile memory.
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index bc54235a7022..a086dd34f932 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -3,7 +3,7 @@ menuconfig AGP
tristate "/dev/agpgart (AGP Support)"
depends on ALPHA || IA64 || PARISC || PPC || X86
depends on PCI
- ---help---
+ help
AGP (Accelerated Graphics Port) is a bus system mainly used to
connect graphics cards to the rest of the system.
@@ -30,7 +30,7 @@ menuconfig AGP
config AGP_ALI
tristate "ALI chipset support"
depends on AGP && X86_32
- ---help---
+ help
This option gives you AGP support for the GLX component of
X on the following ALi chipsets. The supported chipsets
include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
@@ -45,7 +45,7 @@ config AGP_ALI
config AGP_ATI
tristate "ATI chipset support"
depends on AGP && X86_32
- ---help---
+ help
This option gives you AGP support for the GLX component of
X on the ATI RadeonIGP family of chipsets.
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 47098648502d..00ff5fcb808a 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,7 +39,6 @@
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
-#include <asm/pgtable.h>
#include "agp.h"
struct agp_front_data agp_fe;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 9e84239f88d4..3ffbb1c80c5c 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -42,7 +42,6 @@
#ifdef CONFIG_X86
#include <asm/set_memory.h>
#endif
-#include <asm/pgtable.h>
#include "agp.h"
__u32 *agp_gatt_table;
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index e5e5333f302d..cce2af5df7b4 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -17,7 +17,6 @@
#include <linux/list.h>
#include <linux/mm.h>
#include <linux/slab.h>
-#include <asm/pgtable.h>
#include <asm/io.h>
/*
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 9bc46da8d77a..0ad17efc96df 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -6,7 +6,7 @@
menuconfig HW_RANDOM
tristate "Hardware Random Number Generator Core support"
default m
- ---help---
+ help
Hardware Random Number Generator Core infrastructure.
To compile this driver as a module, choose M here: the
@@ -24,7 +24,7 @@ if HW_RANDOM
config HW_RANDOM_TIMERIOMEM
tristate "Timer IOMEM HW Random Number Generator support"
depends on HAS_IOMEM
- ---help---
+ help
This driver provides kernel-side support for a generic Random
Number Generator used by reading a 'dumb' iomem address that
is to be read no faster than, for example, once a second;
@@ -39,7 +39,7 @@ config HW_RANDOM_INTEL
tristate "Intel HW Random Number Generator support"
depends on (X86 || IA64) && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Intel i8xx-based motherboards.
@@ -52,7 +52,7 @@ config HW_RANDOM_AMD
tristate "AMD HW Random Number Generator support"
depends on (X86 || PPC_MAPLE) && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on AMD 76x-based motherboards.
@@ -65,7 +65,7 @@ config HW_RANDOM_ATMEL
tristate "Atmel Random Number Generator support"
depends on ARCH_AT91 && HAVE_CLK && OF
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Atmel AT91 devices.
@@ -79,7 +79,7 @@ config HW_RANDOM_BCM2835
depends on ARCH_BCM2835 || ARCH_BCM_NSP || ARCH_BCM_5301X || \
ARCH_BCM_63XX || BCM63XX || BMIPS_GENERIC
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on the Broadcom BCM2835 and BCM63xx SoCs.
@@ -92,7 +92,7 @@ config HW_RANDOM_IPROC_RNG200
tristate "Broadcom iProc/STB RNG200 support"
depends on ARCH_BCM_IPROC || ARCH_BCM2835 || ARCH_BRCMSTB
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the RNG200
hardware found on the Broadcom iProc and STB SoCs.
@@ -105,7 +105,7 @@ config HW_RANDOM_GEODE
tristate "AMD Geode HW Random Number Generator support"
depends on X86_32 && PCI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on the AMD Geode LX.
@@ -118,7 +118,7 @@ config HW_RANDOM_N2RNG
tristate "Niagara2 Random Number Generator support"
depends on SPARC64
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Niagara2 cpus.
@@ -131,7 +131,7 @@ config HW_RANDOM_VIA
tristate "VIA HW Random Number Generator support"
depends on X86
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on VIA based motherboards.
@@ -144,7 +144,7 @@ config HW_RANDOM_IXP4XX
tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support"
depends on ARCH_IXP4XX
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Pseudo-Random
Number Generator hardware found on the Intel IXP45x/46x NPU.
@@ -157,7 +157,7 @@ config HW_RANDOM_OMAP
tristate "OMAP Random Number Generator support"
depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS || ARCH_MVEBU
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP16xx, OMAP2/3/4/5, AM33xx/AM43xx
multimedia processors, and Marvell Armada 7k/8k SoCs.
@@ -171,7 +171,7 @@ config HW_RANDOM_OMAP3_ROM
tristate "OMAP3 ROM Random Number Generator support"
depends on ARCH_OMAP3
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on OMAP34xx processors.
@@ -184,7 +184,7 @@ config HW_RANDOM_OCTEON
tristate "Octeon Random Number Generator support"
depends on CAVIUM_OCTEON_SOC
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Octeon processors.
@@ -197,7 +197,7 @@ config HW_RANDOM_PASEMI
tristate "PA Semi HW Random Number Generator support"
depends on PPC_PASEMI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on PA Semi PWRficient SoCs.
@@ -209,7 +209,7 @@ config HW_RANDOM_PASEMI
config HW_RANDOM_VIRTIO
tristate "VirtIO Random Number Generator support"
depends on VIRTIO
- ---help---
+ help
This driver provides kernel-side support for the virtual Random Number
Generator hardware.
@@ -220,7 +220,7 @@ config HW_RANDOM_TX4939
tristate "TX4939 Random Number Generator support"
depends on SOC_TX4939
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on TX4939 SoC.
@@ -233,7 +233,7 @@ config HW_RANDOM_MXC_RNGA
tristate "Freescale i.MX RNGA Random Number Generator"
depends on SOC_IMX31
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Freescale i.MX processors.
@@ -247,7 +247,7 @@ config HW_RANDOM_IMX_RNGC
depends on HAS_IOMEM && HAVE_CLK
depends on SOC_IMX25 || COMPILE_TEST
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator Version C hardware found on some Freescale i.MX
processors. Version B is also supported by this driver.
@@ -261,7 +261,7 @@ config HW_RANDOM_NOMADIK
tristate "ST-Ericsson Nomadik Random Number Generator support"
depends on ARCH_NOMADIK
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on ST-Ericsson SoCs (8815 and 8500).
@@ -274,7 +274,7 @@ config HW_RANDOM_PSERIES
tristate "pSeries HW Random Number Generator support"
depends on PPC64 && IBMVIO
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on POWER7+ machines and above
@@ -287,7 +287,7 @@ config HW_RANDOM_POWERNV
tristate "PowerNV Random Number Generator support"
depends on PPC_POWERNV
default HW_RANDOM
- ---help---
+ help
This is the driver for Random Number Generator hardware found
in POWER7+ and above machines for PowerNV platform.
@@ -300,7 +300,7 @@ config HW_RANDOM_HISI
tristate "Hisilicon Random Number Generator support"
depends on HW_RANDOM && ARCH_HISI
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Hisilicon Hip04 and Hip05 SoC.
@@ -325,7 +325,7 @@ config HW_RANDOM_HISI_V2
config HW_RANDOM_ST
tristate "ST Microelectronics HW Random Number Generator support"
depends on HW_RANDOM && ARCH_STI
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on STi series of SoCs.
@@ -336,7 +336,7 @@ config HW_RANDOM_XGENE
tristate "APM X-Gene True Random Number Generator (TRNG) support"
depends on HW_RANDOM && ARCH_XGENE
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on APM X-Gene SoC.
@@ -363,7 +363,7 @@ config HW_RANDOM_PIC32
tristate "Microchip PIC32 Random Number Generator support"
depends on HW_RANDOM && MACH_PIC32
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on a PIC32.
@@ -377,7 +377,7 @@ config HW_RANDOM_MESON
depends on HW_RANDOM
depends on ARCH_MESON || COMPILE_TEST
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Amlogic Meson SoCs.
@@ -390,7 +390,7 @@ config HW_RANDOM_CAVIUM
tristate "Cavium ThunderX Random Number Generator support"
depends on HW_RANDOM && PCI && (ARM64 || (COMPILE_TEST && 64BIT))
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Cavium SoCs.
@@ -404,7 +404,7 @@ config HW_RANDOM_MTK
depends on HW_RANDOM
depends on ARCH_MEDIATEK || COMPILE_TEST
default y
- ---help---
+ help
This driver provides kernel-side support for the Random Number
Generator hardware found on Mediatek SoCs.
@@ -417,7 +417,7 @@ config HW_RANDOM_S390
tristate "S390 True Random Number Generator support"
depends on S390
default HW_RANDOM
- ---help---
+ help
This driver provides kernel-side support for the True
Random Number Generator available as CPACF extension
on modern s390 hardware platforms.
@@ -431,7 +431,7 @@ config HW_RANDOM_EXYNOS
tristate "Samsung Exynos True Random Number Generator support"
depends on ARCH_EXYNOS || COMPILE_TEST
default HW_RANDOM
- ---help---
+ help
This driver provides support for the True Random Number
Generator available in Exynos SoCs.
@@ -474,6 +474,19 @@ config HW_RANDOM_KEYSTONE
help
This option enables Keystone's hardware random generator.
+config HW_RANDOM_CCTRNG
+ tristate "Arm CryptoCell True Random Number Generator support"
+ depends on HAS_IOMEM && OF
+ help
+ Say 'Y' to enable the True Random Number Generator driver for the
+ Arm TrustZone CryptoCell family of processors.
+ Currently the CryptoCell 713 and 703 are supported.
+ The driver is supported only in SoC where Trusted Execution
+ Environment is not used.
+ Choose 'M' to compile this driver as a module. The module
+ will be called cctrng.
+ If unsure, say 'N'.
+
endif # HW_RANDOM
config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index a7801b49ce6c..2c6724735345 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -41,3 +41,4 @@ obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
+obj-$(CONFIG_HW_RANDOM_CCTRNG) += cctrng.o
diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c
new file mode 100644
index 000000000000..619148fb2dc9
--- /dev/null
+++ b/drivers/char/hw_random/cctrng.c
@@ -0,0 +1,735 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/hw_random.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/workqueue.h>
+#include <linux/circ_buf.h>
+#include <linux/completion.h>
+#include <linux/of.h>
+#include <linux/bitfield.h>
+#include <linux/fips.h>
+
+#include "cctrng.h"
+
+#define CC_REG_LOW(name) (name ## _BIT_SHIFT)
+#define CC_REG_HIGH(name) (CC_REG_LOW(name) + name ## _BIT_SIZE - 1)
+#define CC_GENMASK(name) GENMASK(CC_REG_HIGH(name), CC_REG_LOW(name))
+
+#define CC_REG_FLD_GET(reg_name, fld_name, reg_val) \
+ (FIELD_GET(CC_GENMASK(CC_ ## reg_name ## _ ## fld_name), reg_val))
+
+#define CC_HW_RESET_LOOP_COUNT 10
+#define CC_TRNG_SUSPEND_TIMEOUT 3000
+
+/* data circular buffer in words must be:
+ * - of a power-of-2 size (limitation of circ_buf.h macros)
+ * - at least 6, the size generated in the EHR according to HW implementation
+ */
+#define CCTRNG_DATA_BUF_WORDS 32
+
+/* The timeout for the TRNG operation should be calculated with the formula:
+ * Timeout = EHR_NUM * VN_COEFF * EHR_LENGTH * SAMPLE_CNT * SCALE_VALUE
+ * while:
+ * - SAMPLE_CNT is input value from the characterisation process
+ * - all the rest are constants
+ */
+#define EHR_NUM 1
+#define VN_COEFF 4
+#define EHR_LENGTH CC_TRNG_EHR_IN_BITS
+#define SCALE_VALUE 2
+#define CCTRNG_TIMEOUT(smpl_cnt) \
+ (EHR_NUM * VN_COEFF * EHR_LENGTH * smpl_cnt * SCALE_VALUE)
+
+struct cctrng_drvdata {
+ struct platform_device *pdev;
+ void __iomem *cc_base;
+ struct clk *clk;
+ struct hwrng rng;
+ u32 active_rosc;
+ /* Sampling interval for each ring oscillator:
+ * count of ring oscillator cycles between consecutive bits sampling.
+ * Value of 0 indicates non-valid rosc
+ */
+ u32 smpl_ratio[CC_TRNG_NUM_OF_ROSCS];
+
+ u32 data_buf[CCTRNG_DATA_BUF_WORDS];
+ struct circ_buf circ;
+ struct work_struct compwork;
+ struct work_struct startwork;
+
+ /* pending_hw - 1 when HW is pending, 0 when it is idle */
+ atomic_t pending_hw;
+
+ /* protects against multiple concurrent consumers of data_buf */
+ spinlock_t read_lock;
+};
+
+
+/* functions for write/read CC registers */
+static inline void cc_iowrite(struct cctrng_drvdata *drvdata, u32 reg, u32 val)
+{
+ iowrite32(val, (drvdata->cc_base + reg));
+}
+static inline u32 cc_ioread(struct cctrng_drvdata *drvdata, u32 reg)
+{
+ return ioread32(drvdata->cc_base + reg);
+}
+
+
+static int cc_trng_pm_get(struct device *dev)
+{
+ int rc = 0;
+
+ rc = pm_runtime_get_sync(dev);
+
+ /* pm_runtime_get_sync() can return 1 as a valid return code */
+ return (rc == 1 ? 0 : rc);
+}
+
+static void cc_trng_pm_put_suspend(struct device *dev)
+{
+ int rc = 0;
+
+ pm_runtime_mark_last_busy(dev);
+ rc = pm_runtime_put_autosuspend(dev);
+ if (rc)
+ dev_err(dev, "pm_runtime_put_autosuspend returned %x\n", rc);
+}
+
+static int cc_trng_pm_init(struct cctrng_drvdata *drvdata)
+{
+ struct device *dev = &(drvdata->pdev->dev);
+
+ /* must be before the enabling to avoid redundant suspending */
+ pm_runtime_set_autosuspend_delay(dev, CC_TRNG_SUSPEND_TIMEOUT);
+ pm_runtime_use_autosuspend(dev);
+ /* set us as active - note we won't do PM ops until cc_trng_pm_go()! */
+ return pm_runtime_set_active(dev);
+}
+
+static void cc_trng_pm_go(struct cctrng_drvdata *drvdata)
+{
+ struct device *dev = &(drvdata->pdev->dev);
+
+ /* enable the PM module*/
+ pm_runtime_enable(dev);
+}
+
+static void cc_trng_pm_fini(struct cctrng_drvdata *drvdata)
+{
+ struct device *dev = &(drvdata->pdev->dev);
+
+ pm_runtime_disable(dev);
+}
+
+
+static inline int cc_trng_parse_sampling_ratio(struct cctrng_drvdata *drvdata)
+{
+ struct device *dev = &(drvdata->pdev->dev);
+ struct device_node *np = drvdata->pdev->dev.of_node;
+ int rc;
+ int i;
+ /* ret will be set to 0 if at least one rosc has (sampling ratio > 0) */
+ int ret = -EINVAL;
+
+ rc = of_property_read_u32_array(np, "arm,rosc-ratio",
+ drvdata->smpl_ratio,
+ CC_TRNG_NUM_OF_ROSCS);
+ if (rc) {
+ /* arm,rosc-ratio was not found in device tree */
+ return rc;
+ }
+
+ /* verify that at least one rosc has (sampling ratio > 0) */
+ for (i = 0; i < CC_TRNG_NUM_OF_ROSCS; ++i) {
+ dev_dbg(dev, "rosc %d sampling ratio %u",
+ i, drvdata->smpl_ratio[i]);
+
+ if (drvdata->smpl_ratio[i] > 0)
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int cc_trng_change_rosc(struct cctrng_drvdata *drvdata)
+{
+ struct device *dev = &(drvdata->pdev->dev);
+
+ dev_dbg(dev, "cctrng change rosc (was %d)\n", drvdata->active_rosc);
+ drvdata->active_rosc += 1;
+
+ while (drvdata->active_rosc < CC_TRNG_NUM_OF_ROSCS) {
+ if (drvdata->smpl_ratio[drvdata->active_rosc] > 0)
+ return 0;
+
+ drvdata->active_rosc += 1;
+ }
+ return -EINVAL;
+}
+
+
+static void cc_trng_enable_rnd_source(struct cctrng_drvdata *drvdata)
+{
+ u32 max_cycles;
+
+ /* Set watchdog threshold to maximal allowed time (in CPU cycles) */
+ max_cycles = CCTRNG_TIMEOUT(drvdata->smpl_ratio[drvdata->active_rosc]);
+ cc_iowrite(drvdata, CC_RNG_WATCHDOG_VAL_REG_OFFSET, max_cycles);
+
+ /* enable the RND source */
+ cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0x1);
+
+ /* unmask RNG interrupts */
+ cc_iowrite(drvdata, CC_RNG_IMR_REG_OFFSET, (u32)~CC_RNG_INT_MASK);
+}
+
+
+/* increase circular data buffer index (head/tail) */
+static inline void circ_idx_inc(int *idx, int bytes)
+{
+ *idx += (bytes + 3) >> 2;
+ *idx &= (CCTRNG_DATA_BUF_WORDS - 1);
+}
+
+static inline size_t circ_buf_space(struct cctrng_drvdata *drvdata)
+{
+ return CIRC_SPACE(drvdata->circ.head,
+ drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+
+}
+
+static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+ /* current implementation ignores "wait" */
+
+ struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)rng->priv;
+ struct device *dev = &(drvdata->pdev->dev);
+ u32 *buf = (u32 *)drvdata->circ.buf;
+ size_t copied = 0;
+ size_t cnt_w;
+ size_t size;
+ size_t left;
+
+ if (!spin_trylock(&drvdata->read_lock)) {
+ /* concurrent consumers from data_buf cannot be served */
+ dev_dbg_ratelimited(dev, "unable to hold lock\n");
+ return 0;
+ }
+
+ /* copy till end of data buffer (without wrap back) */
+ cnt_w = CIRC_CNT_TO_END(drvdata->circ.head,
+ drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+ size = min((cnt_w<<2), max);
+ memcpy(data, &(buf[drvdata->circ.tail]), size);
+ copied = size;
+ circ_idx_inc(&drvdata->circ.tail, size);
+ /* copy rest of data in data buffer */
+ left = max - copied;
+ if (left > 0) {
+ cnt_w = CIRC_CNT(drvdata->circ.head,
+ drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
+ size = min((cnt_w<<2), left);
+ memcpy(data, &(buf[drvdata->circ.tail]), size);
+ copied += size;
+ circ_idx_inc(&drvdata->circ.tail, size);
+ }
+
+ spin_unlock(&drvdata->read_lock);
+
+ if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
+ if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
+ /* re-check space in buffer to avoid potential race */
+ if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
+ /* increment device's usage counter */
+ int rc = cc_trng_pm_get(dev);
+
+ if (rc) {
+ dev_err(dev,
+ "cc_trng_pm_get returned %x\n",
+ rc);
+ return rc;
+ }
+
+ /* schedule execution of deferred work handler
+ * for filling of data buffer
+ */
+ schedule_work(&drvdata->startwork);
+ } else {
+ atomic_set(&drvdata->pending_hw, 0);
+ }
+ }
+ }
+
+ return copied;
+}
+
+static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata)
+{
+ u32 tmp_smpl_cnt = 0;
+ struct device *dev = &(drvdata->pdev->dev);
+
+ dev_dbg(dev, "cctrng hw trigger.\n");
+
+ /* enable the HW RND clock */
+ cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
+
+ /* do software reset */
+ cc_iowrite(drvdata, CC_RNG_SW_RESET_REG_OFFSET, 0x1);
+ /* in order to verify that the reset has completed,
+ * the sample count need to be verified
+ */
+ do {
+ /* enable the HW RND clock */
+ cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
+
+ /* set sampling ratio (rng_clocks) between consecutive bits */