From: srini@kernel.org
To: gregkh@linuxfoundation.org
Cc: linux-kernel@vger.kernel.org,
Christian Marangi <ansuelsmth@gmail.com>,
Srinivas Kandagatla <srini@kernel.org>
Subject: [PATCH 11/14] nvmem: airoha: Add support for SMC eFUSE
Date: Sat, 30 May 2026 21:53:30 +0100 [thread overview]
Message-ID: <20260530205333.117458-12-srini@kernel.org> (raw)
In-Reply-To: <20260530205333.117458-1-srini@kernel.org>
From: Christian Marangi <ansuelsmth@gmail.com>
Add support for SMC eFUSE on AN7581 SoC. The SoC have 2 set of 2048 bits of
eFUSE that are used to read calibration value for PCIe, Thermal, USB and
other specific info of the SoC like revision and HW device present.
eFuse value are taken by sending SMC command. ATF is responsible of
validaing the data and rejecting reading protected data (like Private
Key). In such case the SMC command will return non-zero value on a0
register.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
---
drivers/nvmem/Kconfig | 13 ++++
drivers/nvmem/Makefile | 2 +
drivers/nvmem/airoha-smc-efuses.c | 125 ++++++++++++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 drivers/nvmem/airoha-smc-efuses.c
diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 78b648e14727..77ff62d1cd01 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -28,6 +28,19 @@ source "drivers/nvmem/layouts/Kconfig"
# Devices
+config NVMEM_AIROHA_SMC_EFUSES
+ tristate "Airoha SMC eFuse support"
+ depends on ARCH_AIROHA || COMPILE_TEST
+ depends on HAVE_ARM_SMCCC
+ default ARCH_AIROHA
+ help
+ Say y here to enable support for reading eFuses on Airoha AN7581
+ SoCs. These are e.g. used to store factory programmed
+ calibration data required for the PCIe or the USB-C PHY or Thermal.
+
+ This driver can also be built as a module. If so, the module will
+ be called nvmem-airoha-smc-efuses.
+
config NVMEM_AN8855_EFUSE
tristate "Airoha AN8855 eFuse support"
depends on COMPILE_TEST
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 7252b8ec88d4..f6f2bc51dee1 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -10,6 +10,8 @@ nvmem_layouts-y := layouts.o
obj-y += layouts/
# Devices
+obj-$(CONFIG_NVMEM_AIROHA_SMC_EFUSES) += nvmem-airoha-smc-efuses.o
+nvmem-airoha-smc-efuses-y := airoha-smc-efuses.o
obj-$(CONFIG_NVMEM_AN8855_EFUSE) += nvmem-an8855-efuse.o
nvmem-an8855-efuse-y := an8855-efuse.o
obj-$(CONFIG_NVMEM_APPLE_EFUSES) += nvmem-apple-efuses.o
diff --git a/drivers/nvmem/airoha-smc-efuses.c b/drivers/nvmem/airoha-smc-efuses.c
new file mode 100644
index 000000000000..e56a99f4aa1f
--- /dev/null
+++ b/drivers/nvmem/airoha-smc-efuses.c
@@ -0,0 +1,125 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author: Christian Marangi <ansuelsmth@gmail.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/nvmem-provider.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+
+#define AIROHA_SMC_EFUSE_FID 0x82000001
+#define AIROHA_SMC_EFUSE_SUB_ID_READ 0x44414552
+
+#define AIROHA_EFUSE_CELLS 64
+
+struct airoha_efuse_bank_priv {
+ u32 bank_index;
+};
+
+static int airoha_efuse_read(void *context, unsigned int offset,
+ void *val, size_t bytes)
+{
+ struct regmap *regmap = context;
+
+ return regmap_bulk_read(regmap, offset,
+ val, bytes / sizeof(u32));
+}
+
+static int airoha_efuse_reg_read(void *context, unsigned int offset,
+ unsigned int *val)
+{
+ struct airoha_efuse_bank_priv *priv = context;
+ struct arm_smccc_res res;
+
+ arm_smccc_1_1_invoke(AIROHA_SMC_EFUSE_FID,
+ AIROHA_SMC_EFUSE_SUB_ID_READ,
+ priv->bank_index, offset, 0, 0, 0, 0, &res);
+
+ /* check if SMC reported an error */
+ if (res.a0)
+ return -EIO;
+
+ *val = res.a1;
+ return 0;
+}
+
+static int airoha_efuse_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ int ret;
+
+ for_each_child_of_node_scoped(dev->of_node, child) {
+ struct nvmem_config nvmem_config = {
+ .size = AIROHA_EFUSE_CELLS * sizeof(u32),
+ .stride = sizeof(u32),
+ .word_size = sizeof(u32),
+ .reg_read = airoha_efuse_read,
+ };
+ struct regmap_config regmap_config = {
+ .reg_read = airoha_efuse_reg_read,
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ };
+ struct airoha_efuse_bank_priv *priv;
+ struct nvmem_device *nvmem;
+ struct regmap *regmap;
+ const char *name;
+ u32 bank;
+
+ ret = of_property_read_u32(child, "reg", &bank);
+ if (ret)
+ return ret;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ name = devm_kasprintf(dev, GFP_KERNEL, "airoha-efuse-%u",
+ bank);
+ if (!name)
+ return -ENOMEM;
+
+ priv->bank_index = bank;
+
+ regmap_config.name = name;
+ regmap = devm_regmap_init(dev, NULL, priv,
+ ®map_config);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ nvmem_config.name = name;
+ nvmem_config.priv = regmap;
+ nvmem_config.dev = dev;
+ nvmem_config.id = bank;
+ nvmem_config.of_node = child;
+ nvmem = devm_nvmem_register(dev, &nvmem_config);
+ if (IS_ERR(nvmem))
+ return PTR_ERR(nvmem);
+ }
+
+ return 0;
+}
+
+static const struct of_device_id airoha_efuse_of_match[] = {
+ { .compatible = "airoha,an7581-efuses", },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, airoha_efuse_of_match);
+
+static struct platform_driver airoha_efuse_driver = {
+ .probe = airoha_efuse_probe,
+ .driver = {
+ .name = "airoha-efuse",
+ .of_match_table = airoha_efuse_of_match,
+ },
+};
+module_platform_driver(airoha_efuse_driver);
+
+MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>");
+MODULE_DESCRIPTION("Driver for Airoha SMC eFUSEs");
+MODULE_LICENSE("GPL");
--
2.53.0
next prev parent reply other threads:[~2026-05-30 20:54 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 20:53 [PATCH 00/14] nvmem: patches for 7.2 srini
2026-05-30 20:53 ` [PATCH 01/14] dt-bindings: nvmem: qfprom: Add glymur compatible srini
2026-05-30 20:53 ` [PATCH 02/14] nvmem: rockchip-otp: alloc clks with main struct srini
2026-05-30 20:53 ` [PATCH 03/14] nvmem: core: Default to read-only if wp-gpios present srini
2026-05-30 20:53 ` [PATCH 04/14] dt-bindings: nvmem: qfprom: qcom: Add Hawi compatible srini
2026-05-30 20:53 ` [PATCH 05/14] nvmem: nintendo-otp: Use of_device_get_match_data() srini
2026-05-30 20:53 ` [PATCH 06/14] dt-bindings: nvmem: qfprom: Add Milos compatible srini
2026-05-30 20:53 ` [PATCH 07/14] dt-bindings: nvmem: lan9662-otpc: Add LAN969x series srini
2026-05-30 20:53 ` [PATCH 08/14] nvmem: lan9662-otp: add support for LAN969x srini
2026-05-30 20:53 ` [PATCH 09/14] dt-bindings: nvmem: qcom,qfprom: Add Shikra compatible srini
2026-05-30 20:53 ` [PATCH 10/14] dt-bindings: nvmem: airoha: add SMC eFuses schema srini
2026-05-30 20:53 ` srini [this message]
2026-05-30 20:53 ` [PATCH 12/14] nvmem: qcom: Unify user-visible "Qualcomm" name srini
2026-05-30 20:53 ` [PATCH 13/14] nvmem: cleanup dead code in Kconfig srini
2026-05-30 20:53 ` [PATCH 14/14] nvmem: layouts: u-boot-env: check earlier for ethaddr length srini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260530205333.117458-12-srini@kernel.org \
--to=srini@kernel.org \
--cc=ansuelsmth@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.