diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index da9befa3d6c4..5c5d7414f78c 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -392,4 +392,16 @@ 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 cc23ce4ffb1f..e0e67a942c4f 100644 --- a/drivers/nvmem/Makefile +++ b/drivers/nvmem/Makefile @@ -77,3 +77,5 @@ 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/qoriq-efuse.c b/drivers/nvmem/qoriq-efuse.c new file mode 100644 index 000000000000..e7fd04d6dd94 --- /dev/null +++ b/drivers/nvmem/qoriq-efuse.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2023 Westermo Network Technologies AB + */ + +#include +#include +#include +#include +#include +#include + +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 "); +MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader"); +MODULE_LICENSE("GPL");