#include <linux/arm-smccc.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h>
#include <linux/of_device.h>
#define STM32_SMC_BSEC 0x82001003
#define STM32_SMC_READ_SHADOW 0x01
#define STM32_SMC_PROG_OTP 0x02
#define STM32_SMC_WRITE_SHADOW 0x03
#define STM32_SMC_READ_OTP 0x04
#define STM32MP15_BSEC_DATA0 0x200
#define STM32MP15_BSEC_NUM_LOWER 32
struct stm32_romem_priv {
static int stm32_romem_read(void *context, unsigned int offset, void *buf,
struct stm32_romem_priv *priv = context;
for (i = offset; i < offset + bytes; i++)
*buf8++ = readb_relaxed(priv->base + i);
static int stm32_bsec_smc(u8 op, u32 otp, u32 data, u32 *result)
#if IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)
struct arm_smccc_res res;
arm_smccc_smc(STM32_SMC_BSEC, op, otp, data, 0, 0, 0, 0, &res);
static int stm32_bsec_read(void *context, unsigned int offset, void *buf,
struct stm32_romem_priv *priv = context;
struct device *dev = priv->cfg.dev;
u32 roffset, rbytes, val;
u8 *buf8 = buf, *val8 = (u8 *)&val;
int i, j = 0, ret, skip_bytes, size;
roffset = rounddown(offset, 4);
skip_bytes = offset & 0x3;
rbytes = roundup(bytes + skip_bytes, 4);
if (roffset + rbytes > priv->cfg.size)
for (i = roffset; (i < roffset + rbytes); i += 4) {
if (otp < STM32MP15_BSEC_NUM_LOWER) {
priv->base + STM32MP15_BSEC_DATA0 + i);