diff --git a/Documentation/devicetree/bindings/nvmem/fsl,t1023-sfp.yaml b/Documentation/devicetree/bindings/nvmem/fsl,t1023-sfp.yaml new file mode 100644 index 0000000000000..df826b40d8cad --- /dev/null +++ b/Documentation/devicetree/bindings/nvmem/fsl,t1023-sfp.yaml @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/nvmem/fsl,t1023-sfp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP QorIQ eFuse support + +maintainers: + - Richard Alpe + +description: + Read support for the eFuses (SFP) on NXP QorIQ series SoC's. + +allOf: + - $ref: nvmem.yaml# + +properties: + compatible: + const: fsl,t1023-sfp + + reg: + maxItems: 1 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + efuse@e8000 { + compatible = "fsl,t1023-sfp"; + reg = <0xe8000 0x1000>; + }; +... diff --git a/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml b/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml index e698098450e11..ac2381e660279 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml @@ -11,6 +11,15 @@ maintainers: - Srinivas Kandagatla properties: + compatible: + oneOf: + - const: mac-base + description: > + Cell with base MAC address to be used for calculating extra relative + addresses. + It can be stored in a plain binary format (cell length 6) or as an + ASCII text like "00:11:22:33:44:55" (cell length 17). + reg: maxItems: 1 @@ -25,6 +34,23 @@ properties: description: Size in bit within the address range specified by reg. +allOf: + - if: + required: [ compatible ] + then: + if: + properties: + compatible: + contains: + const: mac-base + then: + properties: + "#nvmem-cell-cells": + description: The first argument is a MAC address offset. + const: 1 + required: + - "#nvmem-cell-cells" + required: - reg diff --git a/Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml b/Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml index c271537d0714f..9bd34bd5af30d 100644 --- a/Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml +++ b/Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml @@ -44,6 +44,18 @@ examples: #address-cells = <1>; #size-cells = <1>; + mac@100 { + compatible = "mac-base"; + reg = <0x100 0x6>; + #nvmem-cell-cells = <1>; + }; + + mac@110 { + compatible = "mac-base"; + reg = <0x110 0x11>; + #nvmem-cell-cells = <1>; + }; + calibration@4000 { reg = <0x4000 0x100>; }; diff --git a/Documentation/devicetree/bindings/nvmem/nvmem.yaml b/Documentation/devicetree/bindings/nvmem/nvmem.yaml index 9802441006906..9f921d9401422 100644 --- a/Documentation/devicetree/bindings/nvmem/nvmem.yaml +++ b/Documentation/devicetree/bindings/nvmem/nvmem.yaml @@ -49,7 +49,10 @@ properties: patternProperties: "@[0-9a-f]+(,[0-7])?$": type: object - $ref: layouts/fixed-cell.yaml + allOf: + - $ref: layouts/fixed-cell.yaml + - properties: + compatible: false deprecated: true additionalProperties: true diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml index 6cd4682a167dd..bdfc6d36a4005 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml @@ -23,6 +23,7 @@ properties: - qcom,ipq8064-qfprom - qcom,ipq8074-qfprom - qcom,ipq9574-qfprom + - qcom,msm8226-qfprom - qcom,msm8916-qfprom - qcom,msm8974-qfprom - qcom,msm8976-qfprom diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index da9befa3d6c43..5c5d7414f78c2 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 cc23ce4ffb1f1..e0e67a942c4fe 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/brcm_nvram.c b/drivers/nvmem/brcm_nvram.c index 4567c597c87f2..9737104f3b76b 100644 --- a/drivers/nvmem/brcm_nvram.c +++ b/drivers/nvmem/brcm_nvram.c @@ -159,8 +159,7 @@ static int brcm_nvram_probe(struct platform_device *pdev) return -ENOMEM; priv->dev = dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); diff --git a/drivers/nvmem/lpc18xx_otp.c b/drivers/nvmem/lpc18xx_otp.c index 16c92ea85d499..8faed05e3cbeb 100644 --- a/drivers/nvmem/lpc18xx_otp.c +++ b/drivers/nvmem/lpc18xx_otp.c @@ -68,14 +68,12 @@ static int lpc18xx_otp_probe(struct platform_device *pdev) { struct nvmem_device *nvmem; struct lpc18xx_otp *otp; - struct resource *res; otp = devm_kzalloc(&pdev->dev, sizeof(*otp), GFP_KERNEL); if (!otp) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - otp->base = devm_ioremap_resource(&pdev->dev, res); + otp->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(otp->base)) return PTR_ERR(otp->base); diff --git a/drivers/nvmem/meson-mx-efuse.c b/drivers/nvmem/meson-mx-efuse.c index 13eb14316f463..461e3ad87bcdb 100644 --- a/drivers/nvmem/meson-mx-efuse.c +++ b/drivers/nvmem/meson-mx-efuse.c @@ -194,7 +194,6 @@ static int meson_mx_efuse_probe(struct platform_device *pdev) { const struct meson_mx_efuse_platform_data *drvdata; struct meson_mx_efuse *efuse; - struct resource *res; drvdata = of_device_get_match_data(&pdev->dev); if (!drvdata) @@ -204,8 +203,7 @@ static int meson_mx_efuse_probe(struct platform_device *pdev) if (!efuse) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - efuse->base = devm_ioremap_resource(&pdev->dev, res); + efuse->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(efuse->base)) return PTR_ERR(efuse->base); diff --git a/drivers/nvmem/qfprom.c b/drivers/nvmem/qfprom.c index c1e893c8a2478..14814cba2dd65 100644 --- a/drivers/nvmem/qfprom.c +++ b/drivers/nvmem/qfprom.c @@ -374,8 +374,7 @@ static int qfprom_probe(struct platform_device *pdev) return -ENOMEM; /* The corrected section is always provided */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->qfpcorrected = devm_ioremap_resource(dev, res); + priv->qfpcorrected = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->qfpcorrected)) return PTR_ERR(priv->qfpcorrected); @@ -402,12 +401,10 @@ static int qfprom_probe(struct platform_device *pdev) priv->qfpraw = devm_ioremap_resource(dev, res); if (IS_ERR(priv->qfpraw)) return PTR_ERR(priv->qfpraw); - res = platform_get_resource(pdev, IORESOURCE_MEM, 2); - priv->qfpconf = devm_ioremap_resource(dev, res); + priv->qfpconf = devm_platform_ioremap_resource(pdev, 2); if (IS_ERR(priv->qfpconf)) return PTR_ERR(priv->qfpconf); - res = platform_get_resource(pdev, IORESOURCE_MEM, 3); - priv->qfpsecurity = devm_ioremap_resource(dev, res); + priv->qfpsecurity = devm_platform_ioremap_resource(pdev, 3); if (IS_ERR(priv->qfpsecurity)) return PTR_ERR(priv->qfpsecurity); @@ -427,12 +424,8 @@ static int qfprom_probe(struct platform_device *pdev) return PTR_ERR(priv->vcc); priv->secclk = devm_clk_get(dev, "core"); - if (IS_ERR(priv->secclk)) { - ret = PTR_ERR(priv->secclk); - if (ret != -EPROBE_DEFER) - dev_err(dev, "Error getting clock: %d\n", ret); - return ret; - } + if (IS_ERR(priv->secclk)) + return dev_err_probe(dev, PTR_ERR(priv->secclk), "Error getting clock\n"); /* Only enable writing if we have SoC data. */ if (priv->soc_data) diff --git a/drivers/nvmem/qoriq-efuse.c b/drivers/nvmem/qoriq-efuse.c new file mode 100644 index 0000000000000..e7fd04d6dd942 --- /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"); diff --git a/drivers/nvmem/rockchip-efuse.c b/drivers/nvmem/rockchip-efuse.c index e4579de5d0146..4004c5bece423 100644 --- a/drivers/nvmem/rockchip-efuse.c +++ b/drivers/nvmem/rockchip-efuse.c @@ -267,8 +267,7 @@ static int rockchip_efuse_probe(struct platform_device *pdev) if (!efuse) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - efuse->base = devm_ioremap_resource(dev, res); + efuse->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(efuse->base)) return PTR_ERR(efuse->base); diff --git a/drivers/nvmem/stm32-romem.c b/drivers/nvmem/stm32-romem.c index 38d0bf5571290..0f84044bd1ade 100644 --- a/drivers/nvmem/stm32-romem.c +++ b/drivers/nvmem/stm32-romem.c @@ -196,8 +196,7 @@ static int stm32_romem_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); diff --git a/drivers/nvmem/sunxi_sid.c b/drivers/nvmem/sunxi_sid.c index a970f1741cc63..6bfe02ab169a4 100644 --- a/drivers/nvmem/sunxi_sid.c +++ b/drivers/nvmem/sunxi_sid.c @@ -125,7 +125,6 @@ static int sun8i_sid_read_by_reg(void *context, unsigned int offset, static int sunxi_sid_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct resource *res; struct nvmem_config *nvmem_cfg; struct nvmem_device *nvmem; struct sunxi_sid *sid; @@ -142,8 +141,7 @@ static int sunxi_sid_probe(struct platform_device *pdev) return -EINVAL; sid->value_offset = cfg->value_offset; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - sid->base = devm_ioremap_resource(dev, res); + sid->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(sid->base)) return PTR_ERR(sid->base); diff --git a/drivers/nvmem/uniphier-efuse.c b/drivers/nvmem/uniphier-efuse.c index aca910b3b6f89..0a1dbb80537ec 100644 --- a/drivers/nvmem/uniphier-efuse.c +++ b/drivers/nvmem/uniphier-efuse.c @@ -41,8 +41,7 @@ static int uniphier_efuse_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->base)) return PTR_ERR(priv->base);