kernel: backport NVMEM patches queued for the v6.5
This includes some driver changes and support for fixed cells layout.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
(cherry picked from commit 07bdc55515)
			
			
This commit is contained in:
		@@ -0,0 +1,31 @@
 | 
			
		||||
From eebc6573ad940b62a87776db3917e912b4f52d78 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Tom Rix <trix@redhat.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:05 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: imx-ocotp: set varaiable imx_ocotp_layout
 | 
			
		||||
 storage-class-specifier to static
 | 
			
		||||
 | 
			
		||||
smatch reports
 | 
			
		||||
drivers/nvmem/imx-ocotp.c:599:21: warning: symbol
 | 
			
		||||
  'imx_ocotp_layout' was not declared. Should it be static?
 | 
			
		||||
 | 
			
		||||
This variable is only used in one file so should be static.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Tom Rix <trix@redhat.com>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-2-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/imx-ocotp.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/imx-ocotp.c
 | 
			
		||||
+++ b/drivers/nvmem/imx-ocotp.c
 | 
			
		||||
@@ -596,7 +596,7 @@ static void imx_ocotp_fixup_cell_info(st
 | 
			
		||||
 	cell->read_post_process = imx_ocotp_cell_pp;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-struct nvmem_layout imx_ocotp_layout = {
 | 
			
		||||
+static struct nvmem_layout imx_ocotp_layout = {
 | 
			
		||||
 	.fixup_cell_info = imx_ocotp_fixup_cell_info,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
From 8a00fc606312c68b98add8fe8e6f7a013ce29e78 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Alexander Stein <alexander.stein@ew.tq-group.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:06 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: imx-ocotp: Reverse MAC addresses on all i.MX derivates
 | 
			
		||||
 | 
			
		||||
Not just i.MX8M, but all i.MX6/7 (and subtypes) need to reverse the
 | 
			
		||||
MAC address read from fuses. Exceptions are i.MX6SLL and i.MX7ULP which
 | 
			
		||||
do not support ethernet at all.
 | 
			
		||||
 | 
			
		||||
Fixes: d0221a780cbc ("nvmem: imx-ocotp: add support for post processing")
 | 
			
		||||
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
 | 
			
		||||
Tested-by: Richard Leitner <richard.leitner@skidata.com> # imx6q
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-3-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/imx-ocotp.c | 8 +-------
 | 
			
		||||
 1 file changed, 1 insertion(+), 7 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/imx-ocotp.c
 | 
			
		||||
+++ b/drivers/nvmem/imx-ocotp.c
 | 
			
		||||
@@ -97,7 +97,6 @@ struct ocotp_params {
 | 
			
		||||
 	unsigned int bank_address_words;
 | 
			
		||||
 	void (*set_timing)(struct ocotp_priv *priv);
 | 
			
		||||
 	struct ocotp_ctrl_reg ctrl;
 | 
			
		||||
-	bool reverse_mac_address;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int imx_ocotp_wait_for_busy(struct ocotp_priv *priv, u32 flags)
 | 
			
		||||
@@ -545,7 +544,6 @@ static const struct ocotp_params imx8mq_
 | 
			
		||||
 	.bank_address_words = 0,
 | 
			
		||||
 	.set_timing = imx_ocotp_set_imx6_timing,
 | 
			
		||||
 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
 | 
			
		||||
-	.reverse_mac_address = true,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct ocotp_params imx8mm_params = {
 | 
			
		||||
@@ -553,7 +551,6 @@ static const struct ocotp_params imx8mm_
 | 
			
		||||
 	.bank_address_words = 0,
 | 
			
		||||
 	.set_timing = imx_ocotp_set_imx6_timing,
 | 
			
		||||
 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
 | 
			
		||||
-	.reverse_mac_address = true,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct ocotp_params imx8mn_params = {
 | 
			
		||||
@@ -561,7 +558,6 @@ static const struct ocotp_params imx8mn_
 | 
			
		||||
 	.bank_address_words = 0,
 | 
			
		||||
 	.set_timing = imx_ocotp_set_imx6_timing,
 | 
			
		||||
 	.ctrl = IMX_OCOTP_BM_CTRL_DEFAULT,
 | 
			
		||||
-	.reverse_mac_address = true,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct ocotp_params imx8mp_params = {
 | 
			
		||||
@@ -569,7 +565,6 @@ static const struct ocotp_params imx8mp_
 | 
			
		||||
 	.bank_address_words = 0,
 | 
			
		||||
 	.set_timing = imx_ocotp_set_imx6_timing,
 | 
			
		||||
 	.ctrl = IMX_OCOTP_BM_CTRL_8MP,
 | 
			
		||||
-	.reverse_mac_address = true,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct of_device_id imx_ocotp_dt_ids[] = {
 | 
			
		||||
@@ -624,8 +619,7 @@ static int imx_ocotp_probe(struct platfo
 | 
			
		||||
 	imx_ocotp_nvmem_config.size = 4 * priv->params->nregs;
 | 
			
		||||
 	imx_ocotp_nvmem_config.dev = dev;
 | 
			
		||||
 	imx_ocotp_nvmem_config.priv = priv;
 | 
			
		||||
-	if (priv->params->reverse_mac_address)
 | 
			
		||||
-		imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
 | 
			
		||||
+	imx_ocotp_nvmem_config.layout = &imx_ocotp_layout;
 | 
			
		||||
 
 | 
			
		||||
 	priv->config = &imx_ocotp_nvmem_config;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,6 @@
 | 
			
		||||
From 73bcd133c910bff3b6d3b3834d0d14be9444e90a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Thu, 6 Apr 2023 12:46:16 +0200
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:08 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: brcm_nvram: add .read_post_process() for MACs
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
@@ -9,6 +10,9 @@ Content-Transfer-Encoding: 8bit
 | 
			
		||||
2. Calculate relative addresses based on index argument
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-5-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/Kconfig      |  1 +
 | 
			
		||||
 drivers/nvmem/brcm_nvram.c | 28 ++++++++++++++++++++++++++++
 | 
			
		||||
@@ -0,0 +1,166 @@
 | 
			
		||||
From 8dc61364164e79e44c07fa2ac0a7b6939f00d5db Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:13 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: rockchip-otp: Add clks and reg_read to rockchip_data
 | 
			
		||||
 | 
			
		||||
In preparation to support new Rockchip OTP memory devices with different
 | 
			
		||||
clock configurations and register layout, extend rockchip_data struct
 | 
			
		||||
with the related members: clks, num_clks, reg_read.
 | 
			
		||||
 | 
			
		||||
Additionally, to avoid managing redundant driver data, drop num_clks
 | 
			
		||||
member from rockchip_otp struct and update all references to point to
 | 
			
		||||
the equivalent member in rockchip_data.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
 | 
			
		||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-10-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/rockchip-otp.c | 79 ++++++++++++++++++++++--------------
 | 
			
		||||
 1 file changed, 49 insertions(+), 30 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
+++ b/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
@@ -54,21 +54,19 @@
 | 
			
		||||
 
 | 
			
		||||
 #define OTPC_TIMEOUT			10000
 | 
			
		||||
 
 | 
			
		||||
+struct rockchip_data {
 | 
			
		||||
+	int size;
 | 
			
		||||
+	const char * const *clks;
 | 
			
		||||
+	int num_clks;
 | 
			
		||||
+	nvmem_reg_read_t reg_read;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 struct rockchip_otp {
 | 
			
		||||
 	struct device *dev;
 | 
			
		||||
 	void __iomem *base;
 | 
			
		||||
-	struct clk_bulk_data	*clks;
 | 
			
		||||
-	int num_clks;
 | 
			
		||||
+	struct clk_bulk_data *clks;
 | 
			
		||||
 	struct reset_control *rst;
 | 
			
		||||
-};
 | 
			
		||||
-
 | 
			
		||||
-/* list of required clocks */
 | 
			
		||||
-static const char * const rockchip_otp_clocks[] = {
 | 
			
		||||
-	"otp", "apb_pclk", "phy",
 | 
			
		||||
-};
 | 
			
		||||
-
 | 
			
		||||
-struct rockchip_data {
 | 
			
		||||
-	int size;
 | 
			
		||||
+	const struct rockchip_data *data;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int rockchip_otp_reset(struct rockchip_otp *otp)
 | 
			
		||||
@@ -132,29 +130,23 @@ static int rockchip_otp_ecc_enable(struc
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int rockchip_otp_read(void *context, unsigned int offset,
 | 
			
		||||
-			     void *val, size_t bytes)
 | 
			
		||||
+static int px30_otp_read(void *context, unsigned int offset,
 | 
			
		||||
+			 void *val, size_t bytes)
 | 
			
		||||
 {
 | 
			
		||||
 	struct rockchip_otp *otp = context;
 | 
			
		||||
 	u8 *buf = val;
 | 
			
		||||
-	int ret = 0;
 | 
			
		||||
-
 | 
			
		||||
-	ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
 | 
			
		||||
-	if (ret < 0) {
 | 
			
		||||
-		dev_err(otp->dev, "failed to prepare/enable clks\n");
 | 
			
		||||
-		return ret;
 | 
			
		||||
-	}
 | 
			
		||||
+	int ret;
 | 
			
		||||
 
 | 
			
		||||
 	ret = rockchip_otp_reset(otp);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
 		dev_err(otp->dev, "failed to reset otp phy\n");
 | 
			
		||||
-		goto disable_clks;
 | 
			
		||||
+		return ret;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	ret = rockchip_otp_ecc_enable(otp, false);
 | 
			
		||||
 	if (ret < 0) {
 | 
			
		||||
 		dev_err(otp->dev, "rockchip_otp_ecc_enable err\n");
 | 
			
		||||
-		goto disable_clks;
 | 
			
		||||
+		return ret;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	writel(OTPC_USE_USER | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
 | 
			
		||||
@@ -174,8 +166,28 @@ static int rockchip_otp_read(void *conte
 | 
			
		||||
 
 | 
			
		||||
 read_end:
 | 
			
		||||
 	writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
 | 
			
		||||
-disable_clks:
 | 
			
		||||
-	clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int rockchip_otp_read(void *context, unsigned int offset,
 | 
			
		||||
+			     void *val, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	struct rockchip_otp *otp = context;
 | 
			
		||||
+	int ret;
 | 
			
		||||
+
 | 
			
		||||
+	if (!otp->data || !otp->data->reg_read)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
 | 
			
		||||
+	if (ret < 0) {
 | 
			
		||||
+		dev_err(otp->dev, "failed to prepare/enable clks\n");
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ret = otp->data->reg_read(context, offset, val, bytes);
 | 
			
		||||
+
 | 
			
		||||
+	clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
 | 
			
		||||
 
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
@@ -189,8 +201,15 @@ static struct nvmem_config otp_config =
 | 
			
		||||
 	.reg_read = rockchip_otp_read,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const char * const px30_otp_clocks[] = {
 | 
			
		||||
+	"otp", "apb_pclk", "phy",
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static const struct rockchip_data px30_data = {
 | 
			
		||||
 	.size = 0x40,
 | 
			
		||||
+	.clks = px30_otp_clocks,
 | 
			
		||||
+	.num_clks = ARRAY_SIZE(px30_otp_clocks),
 | 
			
		||||
+	.reg_read = px30_otp_read,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct of_device_id rockchip_otp_match[] = {
 | 
			
		||||
@@ -225,21 +244,21 @@ static int rockchip_otp_probe(struct pla
 | 
			
		||||
 	if (!otp)
 | 
			
		||||
 		return -ENOMEM;
 | 
			
		||||
 
 | 
			
		||||
+	otp->data = data;
 | 
			
		||||
 	otp->dev = dev;
 | 
			
		||||
 	otp->base = devm_platform_ioremap_resource(pdev, 0);
 | 
			
		||||
 	if (IS_ERR(otp->base))
 | 
			
		||||
 		return PTR_ERR(otp->base);
 | 
			
		||||
 
 | 
			
		||||
-	otp->num_clks = ARRAY_SIZE(rockchip_otp_clocks);
 | 
			
		||||
-	otp->clks = devm_kcalloc(dev, otp->num_clks,
 | 
			
		||||
-				     sizeof(*otp->clks), GFP_KERNEL);
 | 
			
		||||
+	otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
 | 
			
		||||
+				 GFP_KERNEL);
 | 
			
		||||
 	if (!otp->clks)
 | 
			
		||||
 		return -ENOMEM;
 | 
			
		||||
 
 | 
			
		||||
-	for (i = 0; i < otp->num_clks; ++i)
 | 
			
		||||
-		otp->clks[i].id = rockchip_otp_clocks[i];
 | 
			
		||||
+	for (i = 0; i < data->num_clks; ++i)
 | 
			
		||||
+		otp->clks[i].id = data->clks[i];
 | 
			
		||||
 
 | 
			
		||||
-	ret = devm_clk_bulk_get(dev, otp->num_clks, otp->clks);
 | 
			
		||||
+	ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,62 @@
 | 
			
		||||
From 30fd21cfb1e64ef20035559a8246f5fbf682c40e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:14 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: rockchip-otp: Generalize rockchip_otp_wait_status()
 | 
			
		||||
 | 
			
		||||
In preparation to support additional Rockchip OTP memory devices with
 | 
			
		||||
different register layout, generalize rockchip_otp_wait_status() to
 | 
			
		||||
accept a new parameter for specifying the offset of the status register.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
 | 
			
		||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-11-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/rockchip-otp.c | 11 ++++++-----
 | 
			
		||||
 1 file changed, 6 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
+++ b/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
@@ -90,18 +90,19 @@ static int rockchip_otp_reset(struct roc
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int rockchip_otp_wait_status(struct rockchip_otp *otp, u32 flag)
 | 
			
		||||
+static int rockchip_otp_wait_status(struct rockchip_otp *otp,
 | 
			
		||||
+				    unsigned int reg, u32 flag)
 | 
			
		||||
 {
 | 
			
		||||
 	u32 status = 0;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
-	ret = readl_poll_timeout_atomic(otp->base + OTPC_INT_STATUS, status,
 | 
			
		||||
+	ret = readl_poll_timeout_atomic(otp->base + reg, status,
 | 
			
		||||
 					(status & flag), 1, OTPC_TIMEOUT);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
 	/* clean int status */
 | 
			
		||||
-	writel(flag, otp->base + OTPC_INT_STATUS);
 | 
			
		||||
+	writel(flag, otp->base + reg);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
@@ -123,7 +124,7 @@ static int rockchip_otp_ecc_enable(struc
 | 
			
		||||
 
 | 
			
		||||
 	writel(SBPI_ENABLE_MASK | SBPI_ENABLE, otp->base + OTPC_SBPI_CTRL);
 | 
			
		||||
 
 | 
			
		||||
-	ret = rockchip_otp_wait_status(otp, OTPC_SBPI_DONE);
 | 
			
		||||
+	ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_SBPI_DONE);
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		dev_err(otp->dev, "timeout during ecc_enable\n");
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +157,7 @@ static int px30_otp_read(void *context,
 | 
			
		||||
 		       otp->base + OTPC_USER_ADDR);
 | 
			
		||||
 		writel(OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK,
 | 
			
		||||
 		       otp->base + OTPC_USER_ENABLE);
 | 
			
		||||
-		ret = rockchip_otp_wait_status(otp, OTPC_USER_DONE);
 | 
			
		||||
+		ret = rockchip_otp_wait_status(otp, OTPC_INT_STATUS, OTPC_USER_DONE);
 | 
			
		||||
 		if (ret < 0) {
 | 
			
		||||
 			dev_err(otp->dev, "timeout during read setup\n");
 | 
			
		||||
 			goto read_end;
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
From d325c9dd2b6e94040ca722ddcadcd6af358dd2be Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:15 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: rockchip-otp: Use
 | 
			
		||||
 devm_reset_control_array_get_exclusive()
 | 
			
		||||
 | 
			
		||||
In preparation to support new Rockchip OTP memory devices having
 | 
			
		||||
specific reset configurations, switch devm_reset_control_get() to
 | 
			
		||||
devm_reset_control_array_get_exclusive().
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
 | 
			
		||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-12-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/rockchip-otp.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
+++ b/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
@@ -263,7 +263,7 @@ static int rockchip_otp_probe(struct pla
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	otp->rst = devm_reset_control_get(dev, "phy");
 | 
			
		||||
+	otp->rst = devm_reset_control_array_get_exclusive(dev);
 | 
			
		||||
 	if (IS_ERR(otp->rst))
 | 
			
		||||
 		return PTR_ERR(otp->rst);
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
From 912517345b867a69542dc9f5c2cc3e9d8beaccf5 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:16 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: rockchip-otp: Improve probe error handling
 | 
			
		||||
 | 
			
		||||
Enhance error handling in the probe function by making use of
 | 
			
		||||
dev_err_probe(), which ensures the error code is always printed, in
 | 
			
		||||
addition to the specified error message.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
 | 
			
		||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-13-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/rockchip-otp.c | 21 ++++++++++++---------
 | 
			
		||||
 1 file changed, 12 insertions(+), 9 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
+++ b/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
@@ -235,10 +235,8 @@ static int rockchip_otp_probe(struct pla
 | 
			
		||||
 	int ret, i;
 | 
			
		||||
 
 | 
			
		||||
 	data = of_device_get_match_data(dev);
 | 
			
		||||
-	if (!data) {
 | 
			
		||||
-		dev_err(dev, "failed to get match data\n");
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-	}
 | 
			
		||||
+	if (!data)
 | 
			
		||||
+		return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
 | 
			
		||||
 
 | 
			
		||||
 	otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
 | 
			
		||||
 			   GFP_KERNEL);
 | 
			
		||||
@@ -249,7 +247,8 @@ static int rockchip_otp_probe(struct pla
 | 
			
		||||
 	otp->dev = dev;
 | 
			
		||||
 	otp->base = devm_platform_ioremap_resource(pdev, 0);
 | 
			
		||||
 	if (IS_ERR(otp->base))
 | 
			
		||||
-		return PTR_ERR(otp->base);
 | 
			
		||||
+		return dev_err_probe(dev, PTR_ERR(otp->base),
 | 
			
		||||
+				     "failed to ioremap resource\n");
 | 
			
		||||
 
 | 
			
		||||
 	otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
 | 
			
		||||
 				 GFP_KERNEL);
 | 
			
		||||
@@ -261,18 +260,22 @@ static int rockchip_otp_probe(struct pla
 | 
			
		||||
 
 | 
			
		||||
 	ret = devm_clk_bulk_get(dev, data->num_clks, otp->clks);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
-		return ret;
 | 
			
		||||
+		return dev_err_probe(dev, ret, "failed to get clocks\n");
 | 
			
		||||
 
 | 
			
		||||
 	otp->rst = devm_reset_control_array_get_exclusive(dev);
 | 
			
		||||
 	if (IS_ERR(otp->rst))
 | 
			
		||||
-		return PTR_ERR(otp->rst);
 | 
			
		||||
+		return dev_err_probe(dev, PTR_ERR(otp->rst),
 | 
			
		||||
+				     "failed to get resets\n");
 | 
			
		||||
 
 | 
			
		||||
 	otp_config.size = data->size;
 | 
			
		||||
 	otp_config.priv = otp;
 | 
			
		||||
 	otp_config.dev = dev;
 | 
			
		||||
-	nvmem = devm_nvmem_register(dev, &otp_config);
 | 
			
		||||
 
 | 
			
		||||
-	return PTR_ERR_OR_ZERO(nvmem);
 | 
			
		||||
+	nvmem = devm_nvmem_register(dev, &otp_config);
 | 
			
		||||
+	if (IS_ERR(nvmem))
 | 
			
		||||
+		return dev_err_probe(dev, PTR_ERR(nvmem),
 | 
			
		||||
+				     "failed to register nvmem device\n");
 | 
			
		||||
+	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static struct platform_driver rockchip_otp_driver = {
 | 
			
		||||
@@ -0,0 +1,129 @@
 | 
			
		||||
From 8ab099fafbbc8c9607c399d21a774784a6cb8b45 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:17 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: rockchip-otp: Add support for RK3588
 | 
			
		||||
 | 
			
		||||
Add support for the OTP memory device found on the Rockchip RK3588 SoC.
 | 
			
		||||
 | 
			
		||||
While here, remove the unnecessary 'void *' casts in the OF device ID
 | 
			
		||||
table.
 | 
			
		||||
 | 
			
		||||
Co-developed-by: Finley Xiao <finley.xiao@rock-chips.com>
 | 
			
		||||
Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
 | 
			
		||||
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
 | 
			
		||||
Tested-by: Vincent Legoll <vincent.legoll@gmail.com>
 | 
			
		||||
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-14-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/rockchip-otp.c | 78 +++++++++++++++++++++++++++++++++++-
 | 
			
		||||
 1 file changed, 76 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
+++ b/drivers/nvmem/rockchip-otp.c
 | 
			
		||||
@@ -54,6 +54,19 @@
 | 
			
		||||
 
 | 
			
		||||
 #define OTPC_TIMEOUT			10000
 | 
			
		||||
 
 | 
			
		||||
+/* RK3588 Register */
 | 
			
		||||
+#define RK3588_OTPC_AUTO_CTRL		0x04
 | 
			
		||||
+#define RK3588_OTPC_AUTO_EN		0x08
 | 
			
		||||
+#define RK3588_OTPC_INT_ST		0x84
 | 
			
		||||
+#define RK3588_OTPC_DOUT0		0x20
 | 
			
		||||
+#define RK3588_NO_SECURE_OFFSET		0x300
 | 
			
		||||
+#define RK3588_NBYTES			4
 | 
			
		||||
+#define RK3588_BURST_NUM		1
 | 
			
		||||
+#define RK3588_BURST_SHIFT		8
 | 
			
		||||
+#define RK3588_ADDR_SHIFT		16
 | 
			
		||||
+#define RK3588_AUTO_EN			BIT(0)
 | 
			
		||||
+#define RK3588_RD_DONE			BIT(1)
 | 
			
		||||
+
 | 
			
		||||
 struct rockchip_data {
 | 
			
		||||
 	int size;
 | 
			
		||||
 	const char * const *clks;
 | 
			
		||||
@@ -171,6 +184,52 @@ read_end:
 | 
			
		||||
 	return ret;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int rk3588_otp_read(void *context, unsigned int offset,
 | 
			
		||||
+			   void *val, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	struct rockchip_otp *otp = context;
 | 
			
		||||
+	unsigned int addr_start, addr_end, addr_len;
 | 
			
		||||
+	int ret, i = 0;
 | 
			
		||||
+	u32 data;
 | 
			
		||||
+	u8 *buf;
 | 
			
		||||
+
 | 
			
		||||
+	addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
 | 
			
		||||
+	addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
 | 
			
		||||
+	addr_len = addr_end - addr_start;
 | 
			
		||||
+	addr_start += RK3588_NO_SECURE_OFFSET;
 | 
			
		||||
+
 | 
			
		||||
+	buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
 | 
			
		||||
+	if (!buf)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	while (addr_len--) {
 | 
			
		||||
+		writel((addr_start << RK3588_ADDR_SHIFT) |
 | 
			
		||||
+		       (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
 | 
			
		||||
+		       otp->base + RK3588_OTPC_AUTO_CTRL);
 | 
			
		||||
+		writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
 | 
			
		||||
+
 | 
			
		||||
+		ret = rockchip_otp_wait_status(otp, RK3588_OTPC_INT_ST,
 | 
			
		||||
+					       RK3588_RD_DONE);
 | 
			
		||||
+		if (ret < 0) {
 | 
			
		||||
+			dev_err(otp->dev, "timeout during read setup\n");
 | 
			
		||||
+			goto read_end;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		data = readl(otp->base + RK3588_OTPC_DOUT0);
 | 
			
		||||
+		memcpy(&buf[i], &data, RK3588_NBYTES);
 | 
			
		||||
+
 | 
			
		||||
+		i += RK3588_NBYTES;
 | 
			
		||||
+		addr_start++;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	memcpy(val, buf + offset % RK3588_NBYTES, bytes);
 | 
			
		||||
+
 | 
			
		||||
+read_end:
 | 
			
		||||
+	kfree(buf);
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int rockchip_otp_read(void *context, unsigned int offset,
 | 
			
		||||
 			     void *val, size_t bytes)
 | 
			
		||||
 {
 | 
			
		||||
@@ -213,14 +272,29 @@ static const struct rockchip_data px30_d
 | 
			
		||||
 	.reg_read = px30_otp_read,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const char * const rk3588_otp_clocks[] = {
 | 
			
		||||
+	"otp", "apb_pclk", "phy", "arb",
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct rockchip_data rk3588_data = {
 | 
			
		||||
+	.size = 0x400,
 | 
			
		||||
+	.clks = rk3588_otp_clocks,
 | 
			
		||||
+	.num_clks = ARRAY_SIZE(rk3588_otp_clocks),
 | 
			
		||||
+	.reg_read = rk3588_otp_read,
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static const struct of_device_id rockchip_otp_match[] = {
 | 
			
		||||
 	{
 | 
			
		||||
 		.compatible = "rockchip,px30-otp",
 | 
			
		||||
-		.data = (void *)&px30_data,
 | 
			
		||||
+		.data = &px30_data,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.compatible = "rockchip,rk3308-otp",
 | 
			
		||||
-		.data = (void *)&px30_data,
 | 
			
		||||
+		.data = &px30_data,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.compatible = "rockchip,rk3588-otp",
 | 
			
		||||
+		.data = &rk3588_data,
 | 
			
		||||
 	},
 | 
			
		||||
 	{ /* sentinel */ },
 | 
			
		||||
 };
 | 
			
		||||
@@ -0,0 +1,26 @@
 | 
			
		||||
From 9734408969e978a1c0d5d752be63dd638288e374 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Michal Simek <michal.simek@amd.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:23 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: zynqmp: Switch @xilinx.com emails to @amd.com
 | 
			
		||||
 | 
			
		||||
@xilinx.com is still working but better to switch to new amd.com after
 | 
			
		||||
AMD/Xilinx acquisition.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Michal Simek <michal.simek@amd.com>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-20-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/zynqmp_nvmem.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/zynqmp_nvmem.c
 | 
			
		||||
+++ b/drivers/nvmem/zynqmp_nvmem.c
 | 
			
		||||
@@ -76,6 +76,6 @@ static struct platform_driver zynqmp_nvm
 | 
			
		||||
 
 | 
			
		||||
 module_platform_driver(zynqmp_nvmem_driver);
 | 
			
		||||
 
 | 
			
		||||
-MODULE_AUTHOR("Michal Simek <michal.simek@xilinx.com>, Nava kishore Manne <navam@xilinx.com>");
 | 
			
		||||
+MODULE_AUTHOR("Michal Simek <michal.simek@amd.com>, Nava kishore Manne <nava.kishore.manne@amd.com>");
 | 
			
		||||
 MODULE_DESCRIPTION("ZynqMP NVMEM driver");
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
@@ -0,0 +1,230 @@
 | 
			
		||||
From 22e9e6fcfb5042cb6d6c7874c459b034800092f1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Peng Fan <peng.fan@nxp.com>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:25 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: imx: support i.MX93 OCOTP
 | 
			
		||||
 | 
			
		||||
Add i.MX93 OCOTP support. i.MX93 OCOTP has two parts: Fuse shadow
 | 
			
		||||
block(fsb) and fuse managed by ELE. The FSB part could be directly
 | 
			
		||||
accessed with MMIO, the ELE could only be accessed with ELE API.
 | 
			
		||||
 | 
			
		||||
Currently the ELE API is not ready, so NULL function callback is used,
 | 
			
		||||
but it was tested with downstream ELE API.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Peng Fan <peng.fan@nxp.com>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-22-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/Kconfig         |   9 ++
 | 
			
		||||
 drivers/nvmem/Makefile        |   2 +
 | 
			
		||||
 drivers/nvmem/imx-ocotp-ele.c | 175 ++++++++++++++++++++++++++++++++++
 | 
			
		||||
 3 files changed, 186 insertions(+)
 | 
			
		||||
 create mode 100644 drivers/nvmem/imx-ocotp-ele.c
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/Kconfig
 | 
			
		||||
+++ b/drivers/nvmem/Kconfig
 | 
			
		||||
@@ -83,6 +83,15 @@ config NVMEM_IMX_OCOTP
 | 
			
		||||
 	  This driver can also be built as a module. If so, the module
 | 
			
		||||
 	  will be called nvmem-imx-ocotp.
 | 
			
		||||
 
 | 
			
		||||
+config NVMEM_IMX_OCOTP_ELE
 | 
			
		||||
+	tristate "i.MX On-Chip OTP Controller support"
 | 
			
		||||
+	depends on ARCH_MXC || COMPILE_TEST
 | 
			
		||||
+	depends on HAS_IOMEM
 | 
			
		||||
+	depends on OF
 | 
			
		||||
+	help
 | 
			
		||||
+	  This is a driver for the On-Chip OTP Controller (OCOTP)
 | 
			
		||||
+	  available on i.MX SoCs which has ELE.
 | 
			
		||||
+
 | 
			
		||||
 config NVMEM_IMX_OCOTP_SCU
 | 
			
		||||
 	tristate "i.MX8 SCU On-Chip OTP Controller support"
 | 
			
		||||
 	depends on IMX_SCU
 | 
			
		||||
--- a/drivers/nvmem/Makefile
 | 
			
		||||
+++ b/drivers/nvmem/Makefile
 | 
			
		||||
@@ -18,6 +18,8 @@ obj-$(CONFIG_NVMEM_IMX_IIM)		+= nvmem-im
 | 
			
		||||
 nvmem-imx-iim-y				:= imx-iim.o
 | 
			
		||||
 obj-$(CONFIG_NVMEM_IMX_OCOTP)		+= nvmem-imx-ocotp.o
 | 
			
		||||
 nvmem-imx-ocotp-y			:= imx-ocotp.o
 | 
			
		||||
+obj-$(CONFIG_NVMEM_IMX_OCOTP_ELE)	+= nvmem-imx-ocotp-ele.o
 | 
			
		||||
+nvmem-imx-ocotp-ele-y			:= imx-ocotp-ele.o
 | 
			
		||||
 obj-$(CONFIG_NVMEM_IMX_OCOTP_SCU)	+= nvmem-imx-ocotp-scu.o
 | 
			
		||||
 nvmem-imx-ocotp-scu-y			:= imx-ocotp-scu.o
 | 
			
		||||
 obj-$(CONFIG_NVMEM_JZ4780_EFUSE)	+= nvmem_jz4780_efuse.o
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/drivers/nvmem/imx-ocotp-ele.c
 | 
			
		||||
@@ -0,0 +1,175 @@
 | 
			
		||||
+// SPDX-License-Identifier: GPL-2.0-only
 | 
			
		||||
+/*
 | 
			
		||||
+ * i.MX9 OCOTP fusebox driver
 | 
			
		||||
+ *
 | 
			
		||||
+ * Copyright 2023 NXP
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include <linux/device.h>
 | 
			
		||||
+#include <linux/io.h>
 | 
			
		||||
+#include <linux/module.h>
 | 
			
		||||
+#include <linux/nvmem-provider.h>
 | 
			
		||||
+#include <linux/of_device.h>
 | 
			
		||||
+#include <linux/platform_device.h>
 | 
			
		||||
+#include <linux/slab.h>
 | 
			
		||||
+
 | 
			
		||||
+enum fuse_type {
 | 
			
		||||
+	FUSE_FSB = 1,
 | 
			
		||||
+	FUSE_ELE = 2,
 | 
			
		||||
+	FUSE_INVALID = -1
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct ocotp_map_entry {
 | 
			
		||||
+	u32 start; /* start word */
 | 
			
		||||
+	u32 num; /* num words */
 | 
			
		||||
+	enum fuse_type type;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct ocotp_devtype_data {
 | 
			
		||||
+	u32 reg_off;
 | 
			
		||||
+	char *name;
 | 
			
		||||
+	u32 size;
 | 
			
		||||
+	u32 num_entry;
 | 
			
		||||
+	u32 flag;
 | 
			
		||||
+	nvmem_reg_read_t reg_read;
 | 
			
		||||
+	struct ocotp_map_entry entry[];
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+struct imx_ocotp_priv {
 | 
			
		||||
+	struct device *dev;
 | 
			
		||||
+	void __iomem *base;
 | 
			
		||||
+	struct nvmem_config config;
 | 
			
		||||
+	struct mutex lock;
 | 
			
		||||
+	const struct ocotp_devtype_data *data;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static enum fuse_type imx_ocotp_fuse_type(void *context, u32 index)
 | 
			
		||||
+{
 | 
			
		||||
+	struct imx_ocotp_priv *priv = context;
 | 
			
		||||
+	const struct ocotp_devtype_data *data = priv->data;
 | 
			
		||||
+	u32 start, end;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < data->num_entry; i++) {
 | 
			
		||||
+		start = data->entry[i].start;
 | 
			
		||||
+		end = data->entry[i].start + data->entry[i].num;
 | 
			
		||||
+
 | 
			
		||||
+		if (index >= start && index < end)
 | 
			
		||||
+			return data->entry[i].type;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return FUSE_INVALID;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int imx_ocotp_reg_read(void *context, unsigned int offset, void *val, size_t bytes)
 | 
			
		||||
+{
 | 
			
		||||
+	struct imx_ocotp_priv *priv = context;
 | 
			
		||||
+	void __iomem *reg = priv->base + priv->data->reg_off;
 | 
			
		||||
+	u32 count, index, num_bytes;
 | 
			
		||||
+	enum fuse_type type;
 | 
			
		||||
+	u32 *buf;
 | 
			
		||||
+	void *p;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	index = offset;
 | 
			
		||||
+	num_bytes = round_up(bytes, 4);
 | 
			
		||||
+	count = num_bytes >> 2;
 | 
			
		||||
+
 | 
			
		||||
+	if (count > ((priv->data->size >> 2) - index))
 | 
			
		||||
+		count = (priv->data->size >> 2) - index;
 | 
			
		||||
+
 | 
			
		||||
+	p = kzalloc(num_bytes, GFP_KERNEL);
 | 
			
		||||
+	if (!p)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	mutex_lock(&priv->lock);
 | 
			
		||||
+
 | 
			
		||||
+	buf = p;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = index; i < (index + count); i++) {
 | 
			
		||||
+		type = imx_ocotp_fuse_type(context, i);
 | 
			
		||||
+		if (type == FUSE_INVALID || type == FUSE_ELE) {
 | 
			
		||||
+			*buf++ = 0;
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		*buf++ = readl_relaxed(reg + (i << 2));
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	memcpy(val, (u8 *)p, bytes);
 | 
			
		||||
+
 | 
			
		||||
+	mutex_unlock(&priv->lock);
 | 
			
		||||
+
 | 
			
		||||
+	kfree(p);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static int imx_ele_ocotp_probe(struct platform_device *pdev)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device *dev = &pdev->dev;
 | 
			
		||||
+	struct imx_ocotp_priv *priv;
 | 
			
		||||
+	struct nvmem_device *nvmem;
 | 
			
		||||
+
 | 
			
		||||
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 | 
			
		||||
+	if (!priv)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+
 | 
			
		||||
+	priv->data = of_device_get_match_data(dev);
 | 
			
		||||
+
 | 
			
		||||
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
 | 
			
		||||
+	if (IS_ERR(priv->base))
 | 
			
		||||
+		return PTR_ERR(priv->base);
 | 
			
		||||
+
 | 
			
		||||
+	priv->config.dev = dev;
 | 
			
		||||
+	priv->config.name = "ELE-OCOTP";
 | 
			
		||||
+	priv->config.id = NVMEM_DEVID_AUTO;
 | 
			
		||||
+	priv->config.owner = THIS_MODULE;
 | 
			
		||||
+	priv->config.size = priv->data->size;
 | 
			
		||||
+	priv->config.reg_read = priv->data->reg_read;
 | 
			
		||||
+	priv->config.word_size = 4;
 | 
			
		||||
+	priv->config.stride = 1;
 | 
			
		||||
+	priv->config.priv = priv;
 | 
			
		||||
+	priv->config.read_only = true;
 | 
			
		||||
+	mutex_init(&priv->lock);
 | 
			
		||||
+
 | 
			
		||||
+	nvmem = devm_nvmem_register(dev, &priv->config);
 | 
			
		||||
+	if (IS_ERR(nvmem))
 | 
			
		||||
+		return PTR_ERR(nvmem);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static const struct ocotp_devtype_data imx93_ocotp_data = {
 | 
			
		||||
+	.reg_off = 0x8000,
 | 
			
		||||
+	.reg_read = imx_ocotp_reg_read,
 | 
			
		||||
+	.size = 2048,
 | 
			
		||||
+	.num_entry = 6,
 | 
			
		||||
+	.entry = {
 | 
			
		||||
+		{ 0, 52, FUSE_FSB },
 | 
			
		||||
+		{ 63, 1, FUSE_ELE},
 | 
			
		||||
+		{ 128, 16, FUSE_ELE },
 | 
			
		||||
+		{ 182, 1, FUSE_ELE },
 | 
			
		||||
+		{ 188, 1, FUSE_ELE },
 | 
			
		||||
+		{ 312, 200, FUSE_FSB }
 | 
			
		||||
+	},
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static const struct of_device_id imx_ele_ocotp_dt_ids[] = {
 | 
			
		||||
+	{ .compatible = "fsl,imx93-ocotp", .data = &imx93_ocotp_data, },
 | 
			
		||||
+	{},
 | 
			
		||||
+};
 | 
			
		||||
+MODULE_DEVICE_TABLE(of, imx_ele_ocotp_dt_ids);
 | 
			
		||||
+
 | 
			
		||||
+static struct platform_driver imx_ele_ocotp_driver = {
 | 
			
		||||
+	.driver = {
 | 
			
		||||
+		.name = "imx_ele_ocotp",
 | 
			
		||||
+		.of_match_table = imx_ele_ocotp_dt_ids,
 | 
			
		||||
+	},
 | 
			
		||||
+	.probe = imx_ele_ocotp_probe,
 | 
			
		||||
+};
 | 
			
		||||
+module_platform_driver(imx_ele_ocotp_driver);
 | 
			
		||||
+
 | 
			
		||||
+MODULE_DESCRIPTION("i.MX OCOTP/ELE driver");
 | 
			
		||||
+MODULE_AUTHOR("Peng Fan <peng.fan@nxp.com>");
 | 
			
		||||
+MODULE_LICENSE("GPL");
 | 
			
		||||
@@ -0,0 +1,96 @@
 | 
			
		||||
From 27f699e578b1a72df89dfa3bc42e093a01dc8d10 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
 | 
			
		||||
Date: Sun, 11 Jun 2023 15:03:29 +0100
 | 
			
		||||
Subject: [PATCH] nvmem: core: add support for fixed cells *layout*
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
This adds support for the "fixed-layout" NVMEM layout binding. It allows
 | 
			
		||||
defining NVMEM cells in a layout DT node named "nvmem-layout".
 | 
			
		||||
 | 
			
		||||
While NVMEM subsystem supports layout drivers it has been discussed that
 | 
			
		||||
"fixed-layout" may actually be supperted internally. It's because:
 | 
			
		||||
1. It's a very basic layout
 | 
			
		||||
2. It allows sharing code with legacy syntax parsing
 | 
			
		||||
3. It's safer for soc_device_match() due to -EPROBE_DEFER
 | 
			
		||||
4. This will make the syntax transition easier
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
 | 
			
		||||
Reviewed-by: Michael Walle <michael@walle.cc>
 | 
			
		||||
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
 | 
			
		||||
Message-ID: <20230611140330.154222-26-srinivas.kandagatla@linaro.org>
 | 
			
		||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++---
 | 
			
		||||
 1 file changed, 29 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/nvmem/core.c
 | 
			
		||||
+++ b/drivers/nvmem/core.c
 | 
			
		||||
@@ -696,7 +696,7 @@ static int nvmem_validate_keepouts(struc
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 | 
			
		||||
+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
 | 
			
		||||
 {
 | 
			
		||||
 	struct nvmem_layout *layout = nvmem->layout;
 | 
			
		||||
 	struct device *dev = &nvmem->dev;
 | 
			
		||||
@@ -704,7 +704,7 @@ static int nvmem_add_cells_from_of(struc
 | 
			
		||||
 	const __be32 *addr;
 | 
			
		||||
 	int len, ret;
 | 
			
		||||
 
 | 
			
		||||
-	for_each_child_of_node(dev->of_node, child) {
 | 
			
		||||
+	for_each_child_of_node(np, child) {
 | 
			
		||||
 		struct nvmem_cell_info info = {0};
 | 
			
		||||
 
 | 
			
		||||
 		addr = of_get_property(child, "reg", &len);
 | 
			
		||||
@@ -742,6 +742,28 @@ static int nvmem_add_cells_from_of(struc
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
 | 
			
		||||
+{
 | 
			
		||||
+	return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int nvmem_add_cells_from_fixed_layout(struct nvmem_device *nvmem)
 | 
			
		||||
+{
 | 
			
		||||
+	struct device_node *layout_np;
 | 
			
		||||
+	int err = 0;
 | 
			
		||||
+
 | 
			
		||||
+	layout_np = of_nvmem_layout_get_container(nvmem);
 | 
			
		||||
+	if (!layout_np)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (of_device_is_compatible(layout_np, "fixed-layout"))
 | 
			
		||||
+		err = nvmem_add_cells_from_dt(nvmem, layout_np);
 | 
			
		||||
+
 | 
			
		||||
+	of_node_put(layout_np);
 | 
			
		||||
+
 | 
			
		||||
+	return err;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
 | 
			
		||||
 {
 | 
			
		||||
 	layout->owner = owner;
 | 
			
		||||
@@ -972,7 +994,7 @@ struct nvmem_device *nvmem_register(cons
 | 
			
		||||
 	if (rval)
 | 
			
		||||
 		goto err_remove_cells;
 | 
			
		||||
 
 | 
			
		||||
-	rval = nvmem_add_cells_from_of(nvmem);
 | 
			
		||||
+	rval = nvmem_add_cells_from_legacy_of(nvmem);
 | 
			
		||||
 	if (rval)
 | 
			
		||||
 		goto err_remove_cells;
 | 
			
		||||
 
 | 
			
		||||
@@ -982,6 +1004,10 @@ struct nvmem_device *nvmem_register(cons
 | 
			
		||||
 	if (rval)
 | 
			
		||||
 		goto err_remove_cells;
 | 
			
		||||
 
 | 
			
		||||
+	rval = nvmem_add_cells_from_fixed_layout(nvmem);
 | 
			
		||||
+	if (rval)
 | 
			
		||||
+		goto err_remove_cells;
 | 
			
		||||
+
 | 
			
		||||
 	rval = nvmem_add_cells_from_layout(nvmem);
 | 
			
		||||
 	if (rval)
 | 
			
		||||
 		goto err_remove_cells;
 | 
			
		||||
@@ -295,6 +295,7 @@ CONFIG_NR_CPUS=4
 | 
			
		||||
CONFIG_NVMEM=y
 | 
			
		||||
# CONFIG_NVMEM_IMX_IIM is not set
 | 
			
		||||
CONFIG_NVMEM_IMX_OCOTP=y
 | 
			
		||||
# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
 | 
			
		||||
# CONFIG_NVMEM_SNVS_LPGPR is not set
 | 
			
		||||
CONFIG_NVMEM_SYSFS=y
 | 
			
		||||
CONFIG_OF=y
 | 
			
		||||
 
 | 
			
		||||
@@ -413,6 +413,7 @@ CONFIG_NR_CPUS=16
 | 
			
		||||
CONFIG_NTFS_FS=y
 | 
			
		||||
CONFIG_NVMEM=y
 | 
			
		||||
# CONFIG_NVMEM_IMX_IIM is not set
 | 
			
		||||
# CONFIG_NVMEM_IMX_OCOTP_ELE is not set
 | 
			
		||||
# CONFIG_NVMEM_SNVS_LPGPR is not set
 | 
			
		||||
# CONFIG_NVMEM_SPMI_SDAM is not set
 | 
			
		||||
CONFIG_NVMEM_SYSFS=y
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user