85e1e1ac34
https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.1.100 All patches automatically rebased. Build system: bcm53xx ath79 Signed-off-by: Zxl hhyccc <zxlhhy@gmail.com>
181 lines
5.7 KiB
Diff
181 lines
5.7 KiB
Diff
From 5d8e6e6c10a3d37486d263b16ddc15991a7e4a88 Mon Sep 17 00:00:00 2001
|
|
From: Michael Walle <michael@walle.cc>
|
|
Date: Mon, 6 Feb 2023 13:43:46 +0000
|
|
Subject: [PATCH] nvmem: core: add an index parameter to the cell
|
|
|
|
Sometimes a cell can represend multiple values. For example, a base
|
|
ethernet address stored in the NVMEM can be expanded into multiple
|
|
discreet ones by adding an offset.
|
|
|
|
For this use case, introduce an index parameter which is then used to
|
|
distiguish between values. This parameter will then be passed to the
|
|
post process hook which can then use it to create different values
|
|
during reading.
|
|
|
|
At the moment, there is only support for the device tree path. You can
|
|
add the index to the phandle, e.g.
|
|
|
|
&net {
|
|
nvmem-cells = <&base_mac_address 2>;
|
|
nvmem-cell-names = "mac-address";
|
|
};
|
|
|
|
&nvmem_provider {
|
|
base_mac_address: base-mac-address@0 {
|
|
#nvmem-cell-cells = <1>;
|
|
reg = <0 6>;
|
|
};
|
|
};
|
|
|
|
Signed-off-by: Michael Walle <michael@walle.cc>
|
|
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
|
Link: https://lore.kernel.org/r/20230206134356.839737-13-srinivas.kandagatla@linaro.org
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/nvmem/core.c | 37 ++++++++++++++++++++++++----------
|
|
drivers/nvmem/imx-ocotp.c | 4 ++--
|
|
include/linux/nvmem-provider.h | 4 ++--
|
|
3 files changed, 30 insertions(+), 15 deletions(-)
|
|
|
|
--- a/drivers/nvmem/core.c
|
|
+++ b/drivers/nvmem/core.c
|
|
@@ -60,6 +60,7 @@ struct nvmem_cell_entry {
|
|
struct nvmem_cell {
|
|
struct nvmem_cell_entry *entry;
|
|
const char *id;
|
|
+ int index;
|
|
};
|
|
|
|
static DEFINE_MUTEX(nvmem_mutex);
|
|
@@ -1121,7 +1122,8 @@ struct nvmem_device *devm_nvmem_device_g
|
|
}
|
|
EXPORT_SYMBOL_GPL(devm_nvmem_device_get);
|
|
|
|
-static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, const char *id)
|
|
+static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry,
|
|
+ const char *id, int index)
|
|
{
|
|
struct nvmem_cell *cell;
|
|
const char *name = NULL;
|
|
@@ -1140,6 +1142,7 @@ static struct nvmem_cell *nvmem_create_c
|
|
|
|
cell->id = name;
|
|
cell->entry = entry;
|
|
+ cell->index = index;
|
|
|
|
return cell;
|
|
}
|
|
@@ -1178,7 +1181,7 @@ nvmem_cell_get_from_lookup(struct device
|
|
__nvmem_device_put(nvmem);
|
|
cell = ERR_PTR(-ENOENT);
|
|
} else {
|
|
- cell = nvmem_create_cell(cell_entry, con_id);
|
|
+ cell = nvmem_create_cell(cell_entry, con_id, 0);
|
|
if (IS_ERR(cell))
|
|
__nvmem_device_put(nvmem);
|
|
}
|
|
@@ -1226,15 +1229,27 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
|
struct nvmem_device *nvmem;
|
|
struct nvmem_cell_entry *cell_entry;
|
|
struct nvmem_cell *cell;
|
|
+ struct of_phandle_args cell_spec;
|
|
int index = 0;
|
|
+ int cell_index = 0;
|
|
+ int ret;
|
|
|
|
/* if cell name exists, find index to the name */
|
|
if (id)
|
|
index = of_property_match_string(np, "nvmem-cell-names", id);
|
|
|
|
- cell_np = of_parse_phandle(np, "nvmem-cells", index);
|
|
- if (!cell_np)
|
|
- return ERR_PTR(-ENOENT);
|
|
+ ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
|
|
+ "#nvmem-cell-cells",
|
|
+ index, &cell_spec);
|
|
+ if (ret)
|
|
+ return ERR_PTR(ret);
|
|
+
|
|
+ if (cell_spec.args_count > 1)
|
|
+ return ERR_PTR(-EINVAL);
|
|
+
|
|
+ cell_np = cell_spec.np;
|
|
+ if (cell_spec.args_count)
|
|
+ cell_index = cell_spec.args[0];
|
|
|
|
nvmem_np = of_get_parent(cell_np);
|
|
if (!nvmem_np) {
|
|
@@ -1256,7 +1271,7 @@ struct nvmem_cell *of_nvmem_cell_get(str
|
|
return ERR_PTR(-ENOENT);
|
|
}
|
|
|
|
- cell = nvmem_create_cell(cell_entry, id);
|
|
+ cell = nvmem_create_cell(cell_entry, id, cell_index);
|
|
if (IS_ERR(cell))
|
|
__nvmem_device_put(nvmem);
|
|
|
|
@@ -1409,8 +1424,8 @@ static void nvmem_shift_read_buffer_in_p
|
|
}
|
|
|
|
static int __nvmem_cell_read(struct nvmem_device *nvmem,
|
|
- struct nvmem_cell_entry *cell,
|
|
- void *buf, size_t *len, const char *id)
|
|
+ struct nvmem_cell_entry *cell,
|
|
+ void *buf, size_t *len, const char *id, int index)
|
|
{
|
|
int rc;
|
|
|
|
@@ -1424,7 +1439,7 @@ static int __nvmem_cell_read(struct nvme
|
|
nvmem_shift_read_buffer_in_place(cell, buf);
|
|
|
|
if (nvmem->cell_post_process) {
|
|
- rc = nvmem->cell_post_process(nvmem->priv, id,
|
|
+ rc = nvmem->cell_post_process(nvmem->priv, id, index,
|
|
cell->offset, buf, cell->bytes);
|
|
if (rc)
|
|
return rc;
|
|
@@ -1459,7 +1474,7 @@ void *nvmem_cell_read(struct nvmem_cell
|
|
if (!buf)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
- rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id);
|
|
+ rc = __nvmem_cell_read(nvmem, cell->entry, buf, len, cell->id, cell->index);
|
|
if (rc) {
|
|
kfree(buf);
|
|
return ERR_PTR(rc);
|
|
@@ -1772,7 +1787,7 @@ ssize_t nvmem_device_cell_read(struct nv
|
|
if (rc)
|
|
return rc;
|
|
|
|
- rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL);
|
|
+ rc = __nvmem_cell_read(nvmem, &cell, buf, &len, NULL, 0);
|
|
if (rc)
|
|
return rc;
|
|
|
|
--- a/drivers/nvmem/imx-ocotp.c
|
|
+++ b/drivers/nvmem/imx-ocotp.c
|
|
@@ -222,8 +222,8 @@ read_end:
|
|
return ret;
|
|
}
|
|
|
|
-static int imx_ocotp_cell_pp(void *context, const char *id, unsigned int offset,
|
|
- void *data, size_t bytes)
|
|
+static int imx_ocotp_cell_pp(void *context, const char *id, int index,
|
|
+ unsigned int offset, void *data, size_t bytes)
|
|
{
|
|
struct ocotp_priv *priv = context;
|
|
|
|
--- a/include/linux/nvmem-provider.h
|
|
+++ b/include/linux/nvmem-provider.h
|
|
@@ -20,8 +20,8 @@ typedef int (*nvmem_reg_read_t)(void *pr
|
|
typedef int (*nvmem_reg_write_t)(void *priv, unsigned int offset,
|
|
void *val, size_t bytes);
|
|
/* used for vendor specific post processing of cell data */
|
|
-typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, unsigned int offset,
|
|
- void *buf, size_t bytes);
|
|
+typedef int (*nvmem_cell_post_process_t)(void *priv, const char *id, int index,
|
|
+ unsigned int offset, void *buf, size_t bytes);
|
|
|
|
enum nvmem_type {
|
|
NVMEM_TYPE_UNKNOWN = 0,
|