kernel: backport nvmem changes from v6.9
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
a66f6c1bfb
commit
944dfb1ed6
@ -0,0 +1,69 @@
|
||||
From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
|
||||
From: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:07 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
|
||||
|
||||
The socinfo driver reads chip information from eFuses and does not need
|
||||
any devicetree node. Register it from mtk-efuse.
|
||||
|
||||
While at it, also add the name for this driver's nvmem_config.
|
||||
|
||||
Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
|
||||
struct nvmem_config econfig = {};
|
||||
struct mtk_efuse_priv *priv;
|
||||
const struct mtk_efuse_pdata *pdata;
|
||||
+ struct platform_device *socinfo;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
+ econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
||||
+ if (IS_ERR(nvmem))
|
||||
+ return PTR_ERR(nvmem);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(nvmem);
|
||||
+ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
|
||||
+ PLATFORM_DEVID_AUTO, NULL, 0);
|
||||
+ if (IS_ERR(socinfo))
|
||||
+ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
|
||||
+
|
||||
+ platform_set_drvdata(pdev, socinfo);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
|
||||
@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
|
||||
|
||||
+static void mtk_efuse_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct platform_device *socinfo = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!IS_ERR_OR_NULL(socinfo))
|
||||
+ platform_device_unregister(socinfo);
|
||||
+}
|
||||
+
|
||||
static struct platform_driver mtk_efuse_driver = {
|
||||
.probe = mtk_efuse_probe,
|
||||
+ .remove_new = mtk_efuse_remove,
|
||||
.driver = {
|
||||
.name = "mediatek,efuse",
|
||||
.of_match_table = mtk_efuse_of_match,
|
@ -0,0 +1,97 @@
|
||||
From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:11 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
|
||||
|
||||
- Remove static nvmem_config declaration
|
||||
- Remove zynqmp_nvmem_data
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
|
||||
1 file changed, 12 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Xilinx, Inc.
|
||||
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -11,36 +12,25 @@
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
|
||||
-struct zynqmp_nvmem_data {
|
||||
- struct device *dev;
|
||||
- struct nvmem_device *nvmem;
|
||||
-};
|
||||
|
||||
static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
+ struct device *dev = context;
|
||||
int ret;
|
||||
- int idcode, version;
|
||||
- struct zynqmp_nvmem_data *priv = context;
|
||||
+ int idcode;
|
||||
+ int version;
|
||||
|
||||
ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
*(int *)val = version & SILICON_REVISION_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct nvmem_config econfig = {
|
||||
- .name = "zynqmp-nvmem",
|
||||
- .owner = THIS_MODULE,
|
||||
- .word_size = 1,
|
||||
- .size = 1,
|
||||
- .read_only = true,
|
||||
-};
|
||||
-
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
{ .compatible = "xlnx,zynqmp-nvmem-fw", },
|
||||
{ /* sentinel */ },
|
||||
@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
|
||||
static int zynqmp_nvmem_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
- struct zynqmp_nvmem_data *priv;
|
||||
+ struct nvmem_config econfig = {};
|
||||
|
||||
- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->dev = dev;
|
||||
+ econfig.name = "zynqmp-nvmem";
|
||||
+ econfig.owner = THIS_MODULE;
|
||||
+ econfig.word_size = 1;
|
||||
+ econfig.size = 1;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
+ econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
- econfig.priv = priv;
|
||||
-
|
||||
- priv->nvmem = devm_nvmem_register(dev, &econfig);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(priv->nvmem);
|
||||
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
||||
|
||||
static struct platform_driver zynqmp_nvmem_driver = {
|
@ -0,0 +1,243 @@
|
||||
From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:12 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
|
||||
|
||||
Add support to read/write efuse memory map of ZynqMP.
|
||||
Below are the offsets of ZynqMP efuse memory map
|
||||
0 - SOC version(read only)
|
||||
0xC - 0xFC -ZynqMP specific purpose efuses
|
||||
0x100 - 0x17F - Physical Unclonable Function(PUF)
|
||||
efuses repurposed as user efuses
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 176 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
+#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
@@ -11,24 +12,189 @@
|
||||
#include <linux/firmware/xlnx-zynqmp.h>
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
+#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
|
||||
+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
|
||||
+#define WORD_INBYTES 4
|
||||
+#define SOC_VER_SIZE 0x4
|
||||
+#define EFUSE_MEMORY_SIZE 0x177
|
||||
+#define UNUSED_SPACE 0x8
|
||||
+#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
|
||||
+ EFUSE_MEMORY_SIZE)
|
||||
+#define SOC_VERSION_OFFSET 0x0
|
||||
+#define EFUSE_START_OFFSET 0xC
|
||||
+#define EFUSE_END_OFFSET 0xFC
|
||||
+#define EFUSE_PUF_START_OFFSET 0x100
|
||||
+#define EFUSE_PUF_MID_OFFSET 0x140
|
||||
+#define EFUSE_PUF_END_OFFSET 0x17F
|
||||
+#define EFUSE_NOT_ENABLED 29
|
||||
|
||||
+/*
|
||||
+ * efuse access type
|
||||
+ */
|
||||
+enum efuse_access {
|
||||
+ EFUSE_READ = 0,
|
||||
+ EFUSE_WRITE
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct xilinx_efuse - the basic structure
|
||||
+ * @src: address of the buffer to store the data to be write/read
|
||||
+ * @size: read/write word count
|
||||
+ * @offset: read/write offset
|
||||
+ * @flag: 0 - represents efuse read and 1- represents efuse write
|
||||
+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
|
||||
+ * 1 - represents puf user fuse row number.
|
||||
+ *
|
||||
+ * this structure stores all the required details to
|
||||
+ * read/write efuse memory.
|
||||
+ */
|
||||
+struct xilinx_efuse {
|
||||
+ u64 src;
|
||||
+ u32 size;
|
||||
+ u32 offset;
|
||||
+ enum efuse_access flag;
|
||||
+ u32 pufuserfuse;
|
||||
+};
|
||||
+
|
||||
+static int zynqmp_efuse_access(void *context, unsigned int offset,
|
||||
+ void *val, size_t bytes, enum efuse_access flag,
|
||||
+ unsigned int pufflag)
|
||||
+{
|
||||
+ struct device *dev = context;
|
||||
+ struct xilinx_efuse *efuse;
|
||||
+ dma_addr_t dma_addr;
|
||||
+ dma_addr_t dma_buf;
|
||||
+ size_t words = bytes / WORD_INBYTES;
|
||||
+ int ret;
|
||||
+ int value;
|
||||
+ char *data;
|
||||
|
||||
-static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
- void *val, size_t bytes)
|
||||
+ if (bytes % WORD_INBYTES != 0) {
|
||||
+ dev_err(dev, "Bytes requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 0 && offset % WORD_INBYTES) {
|
||||
+ dev_err(dev, "Offset requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 1 && flag == EFUSE_WRITE) {
|
||||
+ memcpy(&value, val, bytes);
|
||||
+ if ((offset == EFUSE_PUF_START_OFFSET ||
|
||||
+ offset == EFUSE_PUF_MID_OFFSET) &&
|
||||
+ value & P_USER_0_64_UPPER_MASK) {
|
||||
+ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (offset == EFUSE_PUF_END_OFFSET &&
|
||||
+ (value & P_USER_127_LOWER_4_BIT_MASK)) {
|
||||
+ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!efuse)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data = dma_alloc_coherent(dev, sizeof(bytes),
|
||||
+ &dma_buf, GFP_KERNEL);
|
||||
+ if (!data) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto efuse_data_fail;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_WRITE) {
|
||||
+ memcpy(data, val, bytes);
|
||||
+ efuse->flag = EFUSE_WRITE;
|
||||
+ } else {
|
||||
+ efuse->flag = EFUSE_READ;
|
||||
+ }
|
||||
+
|
||||
+ efuse->src = dma_buf;
|
||||
+ efuse->size = words;
|
||||
+ efuse->offset = offset;
|
||||
+ efuse->pufuserfuse = pufflag;
|
||||
+
|
||||
+ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
|
||||
+ if (ret != 0) {
|
||||
+ if (ret == EFUSE_NOT_ENABLED) {
|
||||
+ dev_err(dev, "efuse access is not enabled\n");
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ } else {
|
||||
+ dev_err(dev, "Error in efuse read %x\n", ret);
|
||||
+ ret = -EPERM;
|
||||
+ }
|
||||
+ goto efuse_access_err;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_READ)
|
||||
+ memcpy(val, data, bytes);
|
||||
+efuse_access_err:
|
||||
+ dma_free_coherent(dev, sizeof(bytes),
|
||||
+ data, dma_buf);
|
||||
+efuse_data_fail:
|
||||
+ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ efuse, dma_addr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
|
||||
{
|
||||
struct device *dev = context;
|
||||
int ret;
|
||||
+ int pufflag = 0;
|
||||
int idcode;
|
||||
int version;
|
||||
|
||||
- ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
+
|
||||
+ switch (offset) {
|
||||
+ /* Soc version offset is zero */
|
||||
+ case SOC_VERSION_OFFSET:
|
||||
+ if (bytes != SOC_VER_SIZE)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ break;
|
||||
+ /* Efuse offset starts from 0xc */
|
||||
+ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
|
||||
+ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
|
||||
+ ret = zynqmp_efuse_access(context, offset, val,
|
||||
+ bytes, EFUSE_READ, pufflag);
|
||||
+ break;
|
||||
+ default:
|
||||
+ *(u32 *)val = 0xDEADBEEF;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_write(void *context,
|
||||
+ unsigned int offset, void *val, size_t bytes)
|
||||
+{
|
||||
+ int pufflag = 0;
|
||||
+
|
||||
+ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
|
||||
+ return -EOPNOTSUPP;
|
||||
|
||||
- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
- *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
|
||||
- return 0;
|
||||
+ return zynqmp_efuse_access(context, offset,
|
||||
+ val, bytes, EFUSE_WRITE, pufflag);
|
||||
}
|
||||
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
|
||||
econfig.name = "zynqmp-nvmem";
|
||||
econfig.owner = THIS_MODULE;
|
||||
econfig.word_size = 1;
|
||||
- econfig.size = 1;
|
||||
+ econfig.size = ZYNQMP_NVMEM_SIZE;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
- econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
+ econfig.reg_write = zynqmp_nvmem_write;
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Date: Sat, 24 Feb 2024 11:45:14 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT8183 has not one but two efuse devices. The static name and ID
|
||||
causes the second efuse device to fail to probe, due to duplicate sysfs
|
||||
entries.
|
||||
|
||||
With the rework of the mtk-socinfo driver, lookup by name is no longer
|
||||
necessary. The custom name can simply be dropped.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
- econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
@ -0,0 +1,32 @@
|
||||
From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:16 +0000
|
||||
Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
|
||||
|
||||
The algorithms in nvmem core are built with the constraint that
|
||||
bit_offset < 8. If bit_offset is greater the results are wrong. Print an
|
||||
error if the devicetree 'bits' property is outside of the valid range
|
||||
and abort parsing.
|
||||
|
||||
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -807,6 +807,11 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (addr && len == (2 * sizeof(u32))) {
|
||||
info.bit_offset = be32_to_cpup(addr++);
|
||||
info.nbits = be32_to_cpup(addr);
|
||||
+ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
|
||||
+ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
|
||||
+ of_node_put(child);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
|
||||
info.np = of_node_get(child);
|
@ -0,0 +1,69 @@
|
||||
From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
|
||||
From: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:07 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
|
||||
|
||||
The socinfo driver reads chip information from eFuses and does not need
|
||||
any devicetree node. Register it from mtk-efuse.
|
||||
|
||||
While at it, also add the name for this driver's nvmem_config.
|
||||
|
||||
Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
|
||||
struct nvmem_config econfig = {};
|
||||
struct mtk_efuse_priv *priv;
|
||||
const struct mtk_efuse_pdata *pdata;
|
||||
+ struct platform_device *socinfo;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
+ econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
||||
+ if (IS_ERR(nvmem))
|
||||
+ return PTR_ERR(nvmem);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(nvmem);
|
||||
+ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
|
||||
+ PLATFORM_DEVID_AUTO, NULL, 0);
|
||||
+ if (IS_ERR(socinfo))
|
||||
+ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
|
||||
+
|
||||
+ platform_set_drvdata(pdev, socinfo);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
|
||||
@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
|
||||
|
||||
+static void mtk_efuse_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct platform_device *socinfo = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!IS_ERR_OR_NULL(socinfo))
|
||||
+ platform_device_unregister(socinfo);
|
||||
+}
|
||||
+
|
||||
static struct platform_driver mtk_efuse_driver = {
|
||||
.probe = mtk_efuse_probe,
|
||||
+ .remove_new = mtk_efuse_remove,
|
||||
.driver = {
|
||||
.name = "mediatek,efuse",
|
||||
.of_match_table = mtk_efuse_of_match,
|
@ -0,0 +1,97 @@
|
||||
From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:11 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
|
||||
|
||||
- Remove static nvmem_config declaration
|
||||
- Remove zynqmp_nvmem_data
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
|
||||
1 file changed, 12 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Xilinx, Inc.
|
||||
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -11,36 +12,25 @@
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
|
||||
-struct zynqmp_nvmem_data {
|
||||
- struct device *dev;
|
||||
- struct nvmem_device *nvmem;
|
||||
-};
|
||||
|
||||
static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
+ struct device *dev = context;
|
||||
int ret;
|
||||
- int idcode, version;
|
||||
- struct zynqmp_nvmem_data *priv = context;
|
||||
+ int idcode;
|
||||
+ int version;
|
||||
|
||||
ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
*(int *)val = version & SILICON_REVISION_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct nvmem_config econfig = {
|
||||
- .name = "zynqmp-nvmem",
|
||||
- .owner = THIS_MODULE,
|
||||
- .word_size = 1,
|
||||
- .size = 1,
|
||||
- .read_only = true,
|
||||
-};
|
||||
-
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
{ .compatible = "xlnx,zynqmp-nvmem-fw", },
|
||||
{ /* sentinel */ },
|
||||
@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
|
||||
static int zynqmp_nvmem_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
- struct zynqmp_nvmem_data *priv;
|
||||
+ struct nvmem_config econfig = {};
|
||||
|
||||
- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->dev = dev;
|
||||
+ econfig.name = "zynqmp-nvmem";
|
||||
+ econfig.owner = THIS_MODULE;
|
||||
+ econfig.word_size = 1;
|
||||
+ econfig.size = 1;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
+ econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
- econfig.priv = priv;
|
||||
-
|
||||
- priv->nvmem = devm_nvmem_register(dev, &econfig);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(priv->nvmem);
|
||||
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
||||
|
||||
static struct platform_driver zynqmp_nvmem_driver = {
|
@ -0,0 +1,243 @@
|
||||
From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:12 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
|
||||
|
||||
Add support to read/write efuse memory map of ZynqMP.
|
||||
Below are the offsets of ZynqMP efuse memory map
|
||||
0 - SOC version(read only)
|
||||
0xC - 0xFC -ZynqMP specific purpose efuses
|
||||
0x100 - 0x17F - Physical Unclonable Function(PUF)
|
||||
efuses repurposed as user efuses
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 176 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
+#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
@@ -11,24 +12,189 @@
|
||||
#include <linux/firmware/xlnx-zynqmp.h>
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
+#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
|
||||
+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
|
||||
+#define WORD_INBYTES 4
|
||||
+#define SOC_VER_SIZE 0x4
|
||||
+#define EFUSE_MEMORY_SIZE 0x177
|
||||
+#define UNUSED_SPACE 0x8
|
||||
+#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
|
||||
+ EFUSE_MEMORY_SIZE)
|
||||
+#define SOC_VERSION_OFFSET 0x0
|
||||
+#define EFUSE_START_OFFSET 0xC
|
||||
+#define EFUSE_END_OFFSET 0xFC
|
||||
+#define EFUSE_PUF_START_OFFSET 0x100
|
||||
+#define EFUSE_PUF_MID_OFFSET 0x140
|
||||
+#define EFUSE_PUF_END_OFFSET 0x17F
|
||||
+#define EFUSE_NOT_ENABLED 29
|
||||
|
||||
+/*
|
||||
+ * efuse access type
|
||||
+ */
|
||||
+enum efuse_access {
|
||||
+ EFUSE_READ = 0,
|
||||
+ EFUSE_WRITE
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct xilinx_efuse - the basic structure
|
||||
+ * @src: address of the buffer to store the data to be write/read
|
||||
+ * @size: read/write word count
|
||||
+ * @offset: read/write offset
|
||||
+ * @flag: 0 - represents efuse read and 1- represents efuse write
|
||||
+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
|
||||
+ * 1 - represents puf user fuse row number.
|
||||
+ *
|
||||
+ * this structure stores all the required details to
|
||||
+ * read/write efuse memory.
|
||||
+ */
|
||||
+struct xilinx_efuse {
|
||||
+ u64 src;
|
||||
+ u32 size;
|
||||
+ u32 offset;
|
||||
+ enum efuse_access flag;
|
||||
+ u32 pufuserfuse;
|
||||
+};
|
||||
+
|
||||
+static int zynqmp_efuse_access(void *context, unsigned int offset,
|
||||
+ void *val, size_t bytes, enum efuse_access flag,
|
||||
+ unsigned int pufflag)
|
||||
+{
|
||||
+ struct device *dev = context;
|
||||
+ struct xilinx_efuse *efuse;
|
||||
+ dma_addr_t dma_addr;
|
||||
+ dma_addr_t dma_buf;
|
||||
+ size_t words = bytes / WORD_INBYTES;
|
||||
+ int ret;
|
||||
+ int value;
|
||||
+ char *data;
|
||||
|
||||
-static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
- void *val, size_t bytes)
|
||||
+ if (bytes % WORD_INBYTES != 0) {
|
||||
+ dev_err(dev, "Bytes requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 0 && offset % WORD_INBYTES) {
|
||||
+ dev_err(dev, "Offset requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 1 && flag == EFUSE_WRITE) {
|
||||
+ memcpy(&value, val, bytes);
|
||||
+ if ((offset == EFUSE_PUF_START_OFFSET ||
|
||||
+ offset == EFUSE_PUF_MID_OFFSET) &&
|
||||
+ value & P_USER_0_64_UPPER_MASK) {
|
||||
+ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (offset == EFUSE_PUF_END_OFFSET &&
|
||||
+ (value & P_USER_127_LOWER_4_BIT_MASK)) {
|
||||
+ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!efuse)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data = dma_alloc_coherent(dev, sizeof(bytes),
|
||||
+ &dma_buf, GFP_KERNEL);
|
||||
+ if (!data) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto efuse_data_fail;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_WRITE) {
|
||||
+ memcpy(data, val, bytes);
|
||||
+ efuse->flag = EFUSE_WRITE;
|
||||
+ } else {
|
||||
+ efuse->flag = EFUSE_READ;
|
||||
+ }
|
||||
+
|
||||
+ efuse->src = dma_buf;
|
||||
+ efuse->size = words;
|
||||
+ efuse->offset = offset;
|
||||
+ efuse->pufuserfuse = pufflag;
|
||||
+
|
||||
+ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
|
||||
+ if (ret != 0) {
|
||||
+ if (ret == EFUSE_NOT_ENABLED) {
|
||||
+ dev_err(dev, "efuse access is not enabled\n");
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ } else {
|
||||
+ dev_err(dev, "Error in efuse read %x\n", ret);
|
||||
+ ret = -EPERM;
|
||||
+ }
|
||||
+ goto efuse_access_err;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_READ)
|
||||
+ memcpy(val, data, bytes);
|
||||
+efuse_access_err:
|
||||
+ dma_free_coherent(dev, sizeof(bytes),
|
||||
+ data, dma_buf);
|
||||
+efuse_data_fail:
|
||||
+ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ efuse, dma_addr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
|
||||
{
|
||||
struct device *dev = context;
|
||||
int ret;
|
||||
+ int pufflag = 0;
|
||||
int idcode;
|
||||
int version;
|
||||
|
||||
- ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
+
|
||||
+ switch (offset) {
|
||||
+ /* Soc version offset is zero */
|
||||
+ case SOC_VERSION_OFFSET:
|
||||
+ if (bytes != SOC_VER_SIZE)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ break;
|
||||
+ /* Efuse offset starts from 0xc */
|
||||
+ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
|
||||
+ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
|
||||
+ ret = zynqmp_efuse_access(context, offset, val,
|
||||
+ bytes, EFUSE_READ, pufflag);
|
||||
+ break;
|
||||
+ default:
|
||||
+ *(u32 *)val = 0xDEADBEEF;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_write(void *context,
|
||||
+ unsigned int offset, void *val, size_t bytes)
|
||||
+{
|
||||
+ int pufflag = 0;
|
||||
+
|
||||
+ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
|
||||
+ return -EOPNOTSUPP;
|
||||
|
||||
- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
- *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
|
||||
- return 0;
|
||||
+ return zynqmp_efuse_access(context, offset,
|
||||
+ val, bytes, EFUSE_WRITE, pufflag);
|
||||
}
|
||||
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
|
||||
econfig.name = "zynqmp-nvmem";
|
||||
econfig.owner = THIS_MODULE;
|
||||
econfig.word_size = 1;
|
||||
- econfig.size = 1;
|
||||
+ econfig.size = ZYNQMP_NVMEM_SIZE;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
- econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
+ econfig.reg_write = zynqmp_nvmem_write;
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Date: Sat, 24 Feb 2024 11:45:14 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT8183 has not one but two efuse devices. The static name and ID
|
||||
causes the second efuse device to fail to probe, due to duplicate sysfs
|
||||
entries.
|
||||
|
||||
With the rework of the mtk-socinfo driver, lookup by name is no longer
|
||||
necessary. The custom name can simply be dropped.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
- econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
@ -0,0 +1,32 @@
|
||||
From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:16 +0000
|
||||
Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
|
||||
|
||||
The algorithms in nvmem core are built with the constraint that
|
||||
bit_offset < 8. If bit_offset is greater the results are wrong. Print an
|
||||
error if the devicetree 'bits' property is outside of the valid range
|
||||
and abort parsing.
|
||||
|
||||
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -806,6 +806,11 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (addr && len == (2 * sizeof(u32))) {
|
||||
info.bit_offset = be32_to_cpup(addr++);
|
||||
info.nbits = be32_to_cpup(addr);
|
||||
+ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
|
||||
+ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
|
||||
+ of_node_put(child);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
|
||||
info.np = of_node_get(child);
|
@ -0,0 +1,69 @@
|
||||
From 998f0633773b3432829fe45d2cd2ffb842f3c78e Mon Sep 17 00:00:00 2001
|
||||
From: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:07 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Register MediaTek socinfo driver from efuse
|
||||
|
||||
The socinfo driver reads chip information from eFuses and does not need
|
||||
any devicetree node. Register it from mtk-efuse.
|
||||
|
||||
While at it, also add the name for this driver's nvmem_config.
|
||||
|
||||
Signed-off-by: William-tw Lin <william-tw.lin@mediatek.com>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-3-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -68,6 +68,7 @@ static int mtk_efuse_probe(struct platfo
|
||||
struct nvmem_config econfig = {};
|
||||
struct mtk_efuse_priv *priv;
|
||||
const struct mtk_efuse_pdata *pdata;
|
||||
+ struct platform_device *socinfo;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
@@ -85,11 +86,20 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
+ econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
||||
+ if (IS_ERR(nvmem))
|
||||
+ return PTR_ERR(nvmem);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(nvmem);
|
||||
+ socinfo = platform_device_register_data(&pdev->dev, "mtk-socinfo",
|
||||
+ PLATFORM_DEVID_AUTO, NULL, 0);
|
||||
+ if (IS_ERR(socinfo))
|
||||
+ dev_info(dev, "MediaTek SoC Information will be unavailable\n");
|
||||
+
|
||||
+ platform_set_drvdata(pdev, socinfo);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static const struct mtk_efuse_pdata mtk_mt8186_efuse_pdata = {
|
||||
@@ -108,8 +118,17 @@ static const struct of_device_id mtk_efu
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mtk_efuse_of_match);
|
||||
|
||||
+static void mtk_efuse_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct platform_device *socinfo = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!IS_ERR_OR_NULL(socinfo))
|
||||
+ platform_device_unregister(socinfo);
|
||||
+}
|
||||
+
|
||||
static struct platform_driver mtk_efuse_driver = {
|
||||
.probe = mtk_efuse_probe,
|
||||
+ .remove_new = mtk_efuse_remove,
|
||||
.driver = {
|
||||
.name = "mediatek,efuse",
|
||||
.of_match_table = mtk_efuse_of_match,
|
@ -0,0 +1,97 @@
|
||||
From 29be47fcd6a06ea2e79eeeca6e69ad1e23254a69 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:11 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: zynqmp_nvmem_probe cleanup
|
||||
|
||||
- Remove static nvmem_config declaration
|
||||
- Remove zynqmp_nvmem_data
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-7-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 37 ++++++++++++------------------------
|
||||
1 file changed, 12 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2019 Xilinx, Inc.
|
||||
+ * Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
@@ -11,36 +12,25 @@
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
|
||||
-struct zynqmp_nvmem_data {
|
||||
- struct device *dev;
|
||||
- struct nvmem_device *nvmem;
|
||||
-};
|
||||
|
||||
static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
void *val, size_t bytes)
|
||||
{
|
||||
+ struct device *dev = context;
|
||||
int ret;
|
||||
- int idcode, version;
|
||||
- struct zynqmp_nvmem_data *priv = context;
|
||||
+ int idcode;
|
||||
+ int version;
|
||||
|
||||
ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
- dev_dbg(priv->dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
*(int *)val = version & SILICON_REVISION_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static struct nvmem_config econfig = {
|
||||
- .name = "zynqmp-nvmem",
|
||||
- .owner = THIS_MODULE,
|
||||
- .word_size = 1,
|
||||
- .size = 1,
|
||||
- .read_only = true,
|
||||
-};
|
||||
-
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
{ .compatible = "xlnx,zynqmp-nvmem-fw", },
|
||||
{ /* sentinel */ },
|
||||
@@ -50,21 +40,18 @@ MODULE_DEVICE_TABLE(of, zynqmp_nvmem_mat
|
||||
static int zynqmp_nvmem_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
- struct zynqmp_nvmem_data *priv;
|
||||
+ struct nvmem_config econfig = {};
|
||||
|
||||
- priv = devm_kzalloc(dev, sizeof(struct zynqmp_nvmem_data), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->dev = dev;
|
||||
+ econfig.name = "zynqmp-nvmem";
|
||||
+ econfig.owner = THIS_MODULE;
|
||||
+ econfig.word_size = 1;
|
||||
+ econfig.size = 1;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
+ econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
- econfig.priv = priv;
|
||||
-
|
||||
- priv->nvmem = devm_nvmem_register(dev, &econfig);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(priv->nvmem);
|
||||
+ return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
||||
|
||||
static struct platform_driver zynqmp_nvmem_driver = {
|
@ -0,0 +1,243 @@
|
||||
From 737c0c8d07b5f671c0a33cec95965fcb2d2ea893 Mon Sep 17 00:00:00 2001
|
||||
From: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:12 +0000
|
||||
Subject: [PATCH] nvmem: zynqmp_nvmem: Add support to access efuse
|
||||
|
||||
Add support to read/write efuse memory map of ZynqMP.
|
||||
Below are the offsets of ZynqMP efuse memory map
|
||||
0 - SOC version(read only)
|
||||
0xC - 0xFC -ZynqMP specific purpose efuses
|
||||
0x100 - 0x17F - Physical Unclonable Function(PUF)
|
||||
efuses repurposed as user efuses
|
||||
|
||||
Signed-off-by: Praveen Teja Kundanala <praveen.teja.kundanala@amd.com>
|
||||
Acked-by: Kalyani Akula <Kalyani.akula@amd.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-8-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/zynqmp_nvmem.c | 186 +++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 176 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/nvmem/zynqmp_nvmem.c
|
||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
|
||||
@@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2022 - 2023, Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
+#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/of.h>
|
||||
@@ -11,24 +12,189 @@
|
||||
#include <linux/firmware/xlnx-zynqmp.h>
|
||||
|
||||
#define SILICON_REVISION_MASK 0xF
|
||||
+#define P_USER_0_64_UPPER_MASK GENMASK(31, 16)
|
||||
+#define P_USER_127_LOWER_4_BIT_MASK GENMASK(3, 0)
|
||||
+#define WORD_INBYTES 4
|
||||
+#define SOC_VER_SIZE 0x4
|
||||
+#define EFUSE_MEMORY_SIZE 0x177
|
||||
+#define UNUSED_SPACE 0x8
|
||||
+#define ZYNQMP_NVMEM_SIZE (SOC_VER_SIZE + UNUSED_SPACE + \
|
||||
+ EFUSE_MEMORY_SIZE)
|
||||
+#define SOC_VERSION_OFFSET 0x0
|
||||
+#define EFUSE_START_OFFSET 0xC
|
||||
+#define EFUSE_END_OFFSET 0xFC
|
||||
+#define EFUSE_PUF_START_OFFSET 0x100
|
||||
+#define EFUSE_PUF_MID_OFFSET 0x140
|
||||
+#define EFUSE_PUF_END_OFFSET 0x17F
|
||||
+#define EFUSE_NOT_ENABLED 29
|
||||
|
||||
+/*
|
||||
+ * efuse access type
|
||||
+ */
|
||||
+enum efuse_access {
|
||||
+ EFUSE_READ = 0,
|
||||
+ EFUSE_WRITE
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct xilinx_efuse - the basic structure
|
||||
+ * @src: address of the buffer to store the data to be write/read
|
||||
+ * @size: read/write word count
|
||||
+ * @offset: read/write offset
|
||||
+ * @flag: 0 - represents efuse read and 1- represents efuse write
|
||||
+ * @pufuserfuse:0 - represents non-puf efuses, offset is used for read/write
|
||||
+ * 1 - represents puf user fuse row number.
|
||||
+ *
|
||||
+ * this structure stores all the required details to
|
||||
+ * read/write efuse memory.
|
||||
+ */
|
||||
+struct xilinx_efuse {
|
||||
+ u64 src;
|
||||
+ u32 size;
|
||||
+ u32 offset;
|
||||
+ enum efuse_access flag;
|
||||
+ u32 pufuserfuse;
|
||||
+};
|
||||
+
|
||||
+static int zynqmp_efuse_access(void *context, unsigned int offset,
|
||||
+ void *val, size_t bytes, enum efuse_access flag,
|
||||
+ unsigned int pufflag)
|
||||
+{
|
||||
+ struct device *dev = context;
|
||||
+ struct xilinx_efuse *efuse;
|
||||
+ dma_addr_t dma_addr;
|
||||
+ dma_addr_t dma_buf;
|
||||
+ size_t words = bytes / WORD_INBYTES;
|
||||
+ int ret;
|
||||
+ int value;
|
||||
+ char *data;
|
||||
|
||||
-static int zynqmp_nvmem_read(void *context, unsigned int offset,
|
||||
- void *val, size_t bytes)
|
||||
+ if (bytes % WORD_INBYTES != 0) {
|
||||
+ dev_err(dev, "Bytes requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 0 && offset % WORD_INBYTES) {
|
||||
+ dev_err(dev, "Offset requested should be word aligned\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (pufflag == 1 && flag == EFUSE_WRITE) {
|
||||
+ memcpy(&value, val, bytes);
|
||||
+ if ((offset == EFUSE_PUF_START_OFFSET ||
|
||||
+ offset == EFUSE_PUF_MID_OFFSET) &&
|
||||
+ value & P_USER_0_64_UPPER_MASK) {
|
||||
+ dev_err(dev, "Only lower 4 bytes are allowed to be programmed in P_USER_0 & P_USER_64\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+
|
||||
+ if (offset == EFUSE_PUF_END_OFFSET &&
|
||||
+ (value & P_USER_127_LOWER_4_BIT_MASK)) {
|
||||
+ dev_err(dev, "Only MSB 28 bits are allowed to be programmed for P_USER_127\n");
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ efuse = dma_alloc_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!efuse)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ data = dma_alloc_coherent(dev, sizeof(bytes),
|
||||
+ &dma_buf, GFP_KERNEL);
|
||||
+ if (!data) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto efuse_data_fail;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_WRITE) {
|
||||
+ memcpy(data, val, bytes);
|
||||
+ efuse->flag = EFUSE_WRITE;
|
||||
+ } else {
|
||||
+ efuse->flag = EFUSE_READ;
|
||||
+ }
|
||||
+
|
||||
+ efuse->src = dma_buf;
|
||||
+ efuse->size = words;
|
||||
+ efuse->offset = offset;
|
||||
+ efuse->pufuserfuse = pufflag;
|
||||
+
|
||||
+ zynqmp_pm_efuse_access(dma_addr, (u32 *)&ret);
|
||||
+ if (ret != 0) {
|
||||
+ if (ret == EFUSE_NOT_ENABLED) {
|
||||
+ dev_err(dev, "efuse access is not enabled\n");
|
||||
+ ret = -EOPNOTSUPP;
|
||||
+ } else {
|
||||
+ dev_err(dev, "Error in efuse read %x\n", ret);
|
||||
+ ret = -EPERM;
|
||||
+ }
|
||||
+ goto efuse_access_err;
|
||||
+ }
|
||||
+
|
||||
+ if (flag == EFUSE_READ)
|
||||
+ memcpy(val, data, bytes);
|
||||
+efuse_access_err:
|
||||
+ dma_free_coherent(dev, sizeof(bytes),
|
||||
+ data, dma_buf);
|
||||
+efuse_data_fail:
|
||||
+ dma_free_coherent(dev, sizeof(struct xilinx_efuse),
|
||||
+ efuse, dma_addr);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_read(void *context, unsigned int offset, void *val, size_t bytes)
|
||||
{
|
||||
struct device *dev = context;
|
||||
int ret;
|
||||
+ int pufflag = 0;
|
||||
int idcode;
|
||||
int version;
|
||||
|
||||
- ret = zynqmp_pm_get_chipid(&idcode, &version);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
+
|
||||
+ switch (offset) {
|
||||
+ /* Soc version offset is zero */
|
||||
+ case SOC_VERSION_OFFSET:
|
||||
+ if (bytes != SOC_VER_SIZE)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ ret = zynqmp_pm_get_chipid((u32 *)&idcode, (u32 *)&version);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
+ *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ break;
|
||||
+ /* Efuse offset starts from 0xc */
|
||||
+ case EFUSE_START_OFFSET ... EFUSE_END_OFFSET:
|
||||
+ case EFUSE_PUF_START_OFFSET ... EFUSE_PUF_END_OFFSET:
|
||||
+ ret = zynqmp_efuse_access(context, offset, val,
|
||||
+ bytes, EFUSE_READ, pufflag);
|
||||
+ break;
|
||||
+ default:
|
||||
+ *(u32 *)val = 0xDEADBEEF;
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int zynqmp_nvmem_write(void *context,
|
||||
+ unsigned int offset, void *val, size_t bytes)
|
||||
+{
|
||||
+ int pufflag = 0;
|
||||
+
|
||||
+ if (offset < EFUSE_START_OFFSET || offset > EFUSE_PUF_END_OFFSET)
|
||||
+ return -EOPNOTSUPP;
|
||||
|
||||
- dev_dbg(dev, "Read chipid val %x %x\n", idcode, version);
|
||||
- *(int *)val = version & SILICON_REVISION_MASK;
|
||||
+ if (offset >= EFUSE_PUF_START_OFFSET && offset <= EFUSE_PUF_END_OFFSET)
|
||||
+ pufflag = 1;
|
||||
|
||||
- return 0;
|
||||
+ return zynqmp_efuse_access(context, offset,
|
||||
+ val, bytes, EFUSE_WRITE, pufflag);
|
||||
}
|
||||
|
||||
static const struct of_device_id zynqmp_nvmem_match[] = {
|
||||
@@ -45,11 +211,11 @@ static int zynqmp_nvmem_probe(struct pla
|
||||
econfig.name = "zynqmp-nvmem";
|
||||
econfig.owner = THIS_MODULE;
|
||||
econfig.word_size = 1;
|
||||
- econfig.size = 1;
|
||||
+ econfig.size = ZYNQMP_NVMEM_SIZE;
|
||||
econfig.dev = dev;
|
||||
econfig.add_legacy_fixed_of_cells = true;
|
||||
- econfig.read_only = true;
|
||||
econfig.reg_read = zynqmp_nvmem_read;
|
||||
+ econfig.reg_write = zynqmp_nvmem_write;
|
||||
|
||||
return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &econfig));
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
From 76c345edef754b16cab81ad9452cc49c09e67066 Mon Sep 17 00:00:00 2001
|
||||
From: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Date: Sat, 24 Feb 2024 11:45:14 +0000
|
||||
Subject: [PATCH] nvmem: mtk-efuse: Drop NVMEM device name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The MT8183 has not one but two efuse devices. The static name and ID
|
||||
causes the second efuse device to fail to probe, due to duplicate sysfs
|
||||
entries.
|
||||
|
||||
With the rework of the mtk-socinfo driver, lookup by name is no longer
|
||||
necessary. The custom name can simply be dropped.
|
||||
|
||||
Signed-off-by: Chen-Yu Tsai <wenst@chromium.org>
|
||||
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
|
||||
Tested-by: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-10-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/mtk-efuse.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/mtk-efuse.c
|
||||
+++ b/drivers/nvmem/mtk-efuse.c
|
||||
@@ -86,7 +86,6 @@ static int mtk_efuse_probe(struct platfo
|
||||
econfig.size = resource_size(res);
|
||||
econfig.priv = priv;
|
||||
econfig.dev = dev;
|
||||
- econfig.name = "mtk-efuse";
|
||||
if (pdata->uses_post_processing)
|
||||
econfig.fixup_dt_cell_info = &mtk_efuse_fixup_dt_cell_info;
|
||||
nvmem = devm_nvmem_register(dev, &econfig);
|
@ -0,0 +1,33 @@
|
||||
From 8ec0faf2572216b4e25d6829cd41cf3ee2dab979 Mon Sep 17 00:00:00 2001
|
||||
From: "Ricardo B. Marliere" <ricardo@marliere.net>
|
||||
Date: Sat, 24 Feb 2024 11:45:15 +0000
|
||||
Subject: [PATCH] nvmem: core: make nvmem_layout_bus_type const
|
||||
|
||||
Since commit d492cc2573a0 ("driver core: device.h: make struct bus_type
|
||||
a const *"), the driver core can properly handle constant struct
|
||||
bus_type, move the nvmem_layout_bus_type variable to be a constant
|
||||
structure as well, placing it into read-only memory which can not be
|
||||
modified at runtime.
|
||||
|
||||
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Suggested-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: "Ricardo B. Marliere" <ricardo@marliere.net>
|
||||
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-11-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/layouts.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/nvmem/layouts.c
|
||||
+++ b/drivers/nvmem/layouts.c
|
||||
@@ -45,7 +45,7 @@ static void nvmem_layout_bus_remove(stru
|
||||
return drv->remove(layout);
|
||||
}
|
||||
|
||||
-static struct bus_type nvmem_layout_bus_type = {
|
||||
+static const struct bus_type nvmem_layout_bus_type = {
|
||||
.name = "nvmem-layout",
|
||||
.match = nvmem_layout_bus_match,
|
||||
.probe = nvmem_layout_bus_probe,
|
@ -0,0 +1,32 @@
|
||||
From def3173d4f17b37cecbd74d7c269a080b0b01598 Mon Sep 17 00:00:00 2001
|
||||
From: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Date: Sat, 24 Feb 2024 11:45:16 +0000
|
||||
Subject: [PATCH] nvmem: core: Print error on wrong bits DT property
|
||||
|
||||
The algorithms in nvmem core are built with the constraint that
|
||||
bit_offset < 8. If bit_offset is greater the results are wrong. Print an
|
||||
error if the devicetree 'bits' property is outside of the valid range
|
||||
and abort parsing.
|
||||
|
||||
Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com>
|
||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
Link: https://lore.kernel.org/r/20240224114516.86365-12-srinivas.kandagatla@linaro.org
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/nvmem/core.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
--- a/drivers/nvmem/core.c
|
||||
+++ b/drivers/nvmem/core.c
|
||||
@@ -805,6 +805,11 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (addr && len == (2 * sizeof(u32))) {
|
||||
info.bit_offset = be32_to_cpup(addr++);
|
||||
info.nbits = be32_to_cpup(addr);
|
||||
+ if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
|
||||
+ dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
|
||||
+ of_node_put(child);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
|
||||
info.np = of_node_get(child);
|
@ -96,7 +96,7 @@ string.
|
||||
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
|
||||
{
|
||||
struct device *dev = &nvmem->dev;
|
||||
@@ -814,6 +873,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
@@ -819,6 +878,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (nvmem->fixup_dt_cell_info)
|
||||
nvmem->fixup_dt_cell_info(nvmem, &info);
|
||||
|
||||
|
@ -96,7 +96,7 @@ string.
|
||||
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
|
||||
{
|
||||
struct device *dev = &nvmem->dev;
|
||||
@@ -813,6 +872,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
@@ -818,6 +877,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (nvmem->fixup_dt_cell_info)
|
||||
nvmem->fixup_dt_cell_info(nvmem, &info);
|
||||
|
||||
|
@ -96,7 +96,7 @@ string.
|
||||
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
|
||||
{
|
||||
struct device *dev = &nvmem->dev;
|
||||
@@ -812,6 +871,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
@@ -817,6 +876,25 @@ static int nvmem_add_cells_from_dt(struc
|
||||
if (nvmem->fixup_dt_cell_info)
|
||||
nvmem->fixup_dt_cell_info(nvmem, &info);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user