[PATCH 2/2] nvmem: Remove qoriq-efuse in favor of layerscape-sfp

Sean Anderson
2024-03-16T00:20:36Z

The qoriq-efuse driver is a duplicate of layerscape-sfp.c. The T-series
uses TA 2.0, while Layerscape uses TA 2.1 or 3.0 (depending on the
chip). Add appropriate compatibles to the layerscape-sfp driver and
remove the qoriq-efuse driver. I did not add support for P-series SoCs,
since they use TA 1.0 which doesn't share a major version with either of
the existing implementations.

The qoriq-efuse driver does not properly abstract the location/offset of
the fuses properly, instead exposing the device's whole address range to
userspace. This is not appropriate, as the fuses only occupy a small
portion of this range. The layerscape-sfp module correctly constrains
the nvmem size to the fuses size. This represents a (necessary)
compatibility break. The qoriq-efuse driver has been in-tree for around
six months. Hopefully this will limit the fallout.

I would appreciate if someone with access to trust architecture 2.0 user
guide could confirm the number of fuses.

Fixes: 0861110bb421 ("nvmem: add new NXP QorIQ eFuse driver")
Signed-off-by: Sean Anderson <sean.anderson@linux.dev>
---

drivers/nvmem/Kconfig | 14 +-----
drivers/nvmem/Makefile | 2 -
drivers/nvmem/layerscape-sfp.c | 27 +++++++++---
drivers/nvmem/qoriq-efuse.c | 78 ----------------------------------
4 files changed, 22 insertions(+), 99 deletions(-)
delete mode 100644 drivers/nvmem/qoriq-efuse.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index 5bc9c4874fe3..81531ebb073d 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -122,7 +122,7 @@ config NVMEM_LAN9662_OTPC

config NVMEM_LAYERSCAPE_SFP
tristate "Layerscape SFP (Security Fuse Processor) support"
- depends on ARCH_LAYERSCAPE || COMPILE_TEST
+ depends on ARCH_LAYERSCAPE || PPC_85xx || COMPILE_TEST
depends on HAS_IOMEM
select REGMAP_MMIO
help
@@ -405,16 +405,4 @@ config NVMEM_ZYNQMP

If sure, say yes. If unsure, say no.

-config NVMEM_QORIQ_EFUSE
- tristate "NXP QorIQ eFuse support"
- depends on PPC_85xx || COMPILE_TEST
- depends on HAS_IOMEM
- help
- This driver provides read support for the eFuses (SFP) on NXP QorIQ
- series SoC's. This includes secure boot settings, the globally unique
- NXP ID 'FUIDR' and the OEM unique ID 'OUIDR'.
-
- This driver can also be built as a module. If so, the module
- will be called nvmem_qoriq_efuse.
-
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index 423baf089515..a276447b8c2f 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -79,5 +79,3 @@ obj-$(CONFIG_NVMEM_VF610_OCOTP) += nvmem-vf610-ocotp.o
nvmem-vf610-ocotp-y := vf610-ocotp.o
obj-$(CONFIG_NVMEM_ZYNQMP) += nvmem_zynqmp_nvmem.o
nvmem_zynqmp_nvmem-y := zynqmp_nvmem.o
-obj-$(CONFIG_NVMEM_QORIQ_EFUSE) += nvmem-qoriq-efuse.o
-nvmem-qoriq-efuse-y := qoriq-efuse.o
diff --git a/drivers/nvmem/layerscape-sfp.c b/drivers/nvmem/layerscape-sfp.c
index e2b424561949..7e32133e492a 100644
--- a/drivers/nvmem/layerscape-sfp.c
+++ b/drivers/nvmem/layerscape-sfp.c
@@ -22,8 +22,9 @@ struct layerscape_sfp_priv {
};

struct layerscape_sfp_data {
- int size;
+ int size, id;
enum regmap_endian endian;
+ const char *name;
};

static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
@@ -37,7 +38,6 @@ static int layerscape_sfp_read(void *context, unsigned int offset, void *val,
}

static struct nvmem_config layerscape_sfp_nvmem_config = {
- .name = "fsl-sfp",
.reg_read = layerscape_sfp_read,
.word_size = 4,
.stride = 4,
@@ -69,6 +69,8 @@ static int layerscape_sfp_probe(struct platform_device *pdev)
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);

+ layerscape_sfp_nvmem_config.name = data->name;
+ layerscape_sfp_nvmem_config.id = data->id;
layerscape_sfp_nvmem_config.size = data->size;
layerscape_sfp_nvmem_config.dev = &pdev->dev;
layerscape_sfp_nvmem_config.priv = priv;
@@ -78,19 +80,32 @@ static int layerscape_sfp_probe(struct platform_device *pdev)
return PTR_ERR_OR_ZERO(nvmem);
}

-static const struct layerscape_sfp_data ls1021a_data = {
+static const struct layerscape_sfp_data ta2_0_data = {
.size = 0x88,
.endian = REGMAP_ENDIAN_BIG,
+ .name = "qoriq_efuse_read",
+ .id = NVMEM_DEVID_AUTO,
};

-static const struct layerscape_sfp_data ls1028a_data = {
+static const struct layerscape_sfp_data ta2_1_data = {
+ .size = 0x88,
+ .endian = REGMAP_ENDIAN_BIG,
+ .name = "fsl-sfp",
+};
+
+static const struct layerscape_sfp_data ta3_0_data = {
.size = 0x88,
.endian = REGMAP_ENDIAN_LITTLE,
+ .name = "fsl-sfp",
};

static const struct of_device_id layerscape_sfp_dt_ids[] = {
- { .compatible = "fsl,ls1021a-sfp", .data = &ls1021a_data },
- { .compatible = "fsl,ls1028a-sfp", .data = &ls1028a_data },
+ { .compatible = "fsl,ls1021a-sfp", .data = &ta2_1_data },
+ { .compatible = "fsl,ls1028a-sfp", .data = &ta3_0_data },
+ { .compatible = "fsl,t1023-sfp", .data = &ta2_0_data },
+ { .compatible = "fsl,t1040-sfp", .data = &ta2_0_data },
+ { .compatible = "fsl,t2080-sfp", .data = &ta2_0_data },
+ { .compatible = "fsl,t4240-sfp", .data = &ta2_0_data },
{},
};
MODULE_DEVICE_TABLE(of, layerscape_sfp_dt_ids);
diff --git a/drivers/nvmem/qoriq-efuse.c b/drivers/nvmem/qoriq-efuse.c
deleted file mode 100644
index e7fd04d6dd94..000000000000
--- a/drivers/nvmem/qoriq-efuse.c
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2023 Westermo Network Technologies AB
- */
-
-#include <linux/device.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/nvmem-provider.h>
-#include <linux/platform_device.h>
-
-struct qoriq_efuse_priv {
- void __iomem *base;
-};
-
-static int qoriq_efuse_read(void *context, unsigned int offset, void *val,
- size_t bytes)
-{
- struct qoriq_efuse_priv *priv = context;
-
- /* .stride = 4 so offset is guaranteed to be aligned */
- __ioread32_copy(val, priv->base + offset, bytes / 4);
-
- /* Ignore trailing bytes (there shouldn't be any) */
-
- return 0;
-}
-
-static int qoriq_efuse_probe(struct platform_device *pdev)
-{
- struct nvmem_config config = {
- .dev = &pdev->dev,
- .read_only = true,
- .reg_read = qoriq_efuse_read,
- .stride = sizeof(u32),
- .word_size = sizeof(u32),
- .name = "qoriq_efuse_read",
- .id = NVMEM_DEVID_AUTO,
- .root_only = true,
- };
- struct qoriq_efuse_priv *priv;
- struct nvmem_device *nvmem;
- struct resource *res;
-
- priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
-
- priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(priv->base))
- return PTR_ERR(priv->base);
-
- config.size = resource_size(res);
- config.priv = priv;
- nvmem = devm_nvmem_register(config.dev, &config);
-
- return PTR_ERR_OR_ZERO(nvmem);
-}
-
-static const struct of_device_id qoriq_efuse_of_match[] = {
- { .compatible = "fsl,t1023-sfp", },
- {/* sentinel */},
-};
-MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match);
-
-static struct platform_driver qoriq_efuse_driver = {
- .probe = qoriq_efuse_probe,
- .driver = {
- .name = "qoriq-efuse",
- .of_match_table = qoriq_efuse_of_match,
- },
-};
-module_platform_driver(qoriq_efuse_driver);
-
-MODULE_AUTHOR("Richard Alpe <richard.alpe@bit42.se>");
-MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader");
-MODULE_LICENSE("GPL");
--
2.35.1.1320.gc452695387.dirty