kernel: backport more NVMEM changes queued for v6.8

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
Rafał Miłecki 2024-01-05 11:31:26 +01:00
parent 934873f451
commit 04ed95d1f9
14 changed files with 982 additions and 6 deletions

View File

@ -0,0 +1,94 @@
From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 19 Dec 2023 13:01:03 +0100
Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simply pass whole "struct nvmem_layout" instead of single variables.
There is nothing in "struct nvmem_layout" that we have to hide from
layout drivers. They also access it during .probe() and .remove().
Thanks to this change:
1. API gets more consistent
All layouts drivers callbacks get the same argument
2. Layouts get correct device
Before this change NVMEM core code was passing NVMEM device instead
of layout device. That resulted in:
* Confusing prints
* Calling devm_*() helpers on wrong device
* Helpers like of_device_get_match_data() dereferencing NULLs
3. It gets possible to get match data
First of all nvmem_layout_get_match_data() requires passing "struct
nvmem_layout" which .add_cells() callback didn't have before this. It
doesn't matter much as it's rather useless now anyway (and will be
dropped).
What's more important however is that of_device_get_match_data() can
be used now thanks to owning a proper device pointer.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 2 +-
drivers/nvmem/layouts/onie-tlv.c | 4 +++-
drivers/nvmem/layouts/sl28vpd.c | 4 +++-
include/linux/nvmem-provider.h | 2 +-
4 files changed, 8 insertions(+), 4 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l
return -EINVAL;
/* Populate the cells */
- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
+ ret = layout->add_cells(layout);
if (ret)
return ret;
--- a/drivers/nvmem/layouts/onie-tlv.c
+++ b/drivers/nvmem/layouts/onie-tlv.c
@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct
return true;
}
-static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
+static int onie_tlv_parse_table(struct nvmem_layout *layout)
{
+ struct nvmem_device *nvmem = layout->nvmem;
+ struct device *dev = &layout->dev;
struct onie_tlv_hdr hdr;
size_t table_len, data_len, hdr_len;
u8 *table, *data;
--- a/drivers/nvmem/layouts/sl28vpd.c
+++ b/drivers/nvmem/layouts/sl28vpd.c
@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d
return 0;
}
-static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
+static int sl28vpd_add_cells(struct nvmem_layout *layout)
{
+ struct nvmem_device *nvmem = layout->nvmem;
+ struct device *dev = &layout->dev;
const struct nvmem_cell_info *pinfo;
struct nvmem_cell_info info = {0};
struct device_node *layout_np;
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -173,7 +173,7 @@ struct nvmem_cell_table {
struct nvmem_layout {
struct device dev;
struct nvmem_device *nvmem;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
+ int (*add_cells)(struct nvmem_layout *layout);
};
struct nvmem_layout_driver {

View File

@ -0,0 +1,72 @@
From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 19 Dec 2023 13:01:04 +0100
Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Thanks for layouts refactoring we now have "struct device" associated
with layout. Also its OF pointer points directly to the "nvmem-layout"
DT node.
All it takes to get match data is a generic of_device_get_match_data().
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 13 -------------
include/linux/nvmem-provider.h | 10 ----------
2 files changed, 23 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme
}
EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
-{
- struct device_node __maybe_unused *layout_np;
- const struct of_device_id *match;
-
- layout_np = of_nvmem_layout_get_container(nvmem);
- match = of_match_node(layout->dev.driver->of_match_table, layout_np);
-
- return match ? match->data : NULL;
-}
-EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
-
/**
* nvmem_register() - Register a nvmem device for given nvmem_config.
* Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru
module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
nvmem_layout_driver_unregister)
-const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-
#else
static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -238,13 +235,6 @@ static inline int nvmem_layout_register(
static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-static inline const void *
-nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
-{
- return NULL;
-}
-
#endif /* CONFIG_NVMEM */
#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)

View File

@ -0,0 +1,53 @@
From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:17 +0100
Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is required by layouts that need to read whole NVMEM content. It's
especially useful for NVMEM devices without hardcoded layout (like
U-Boot environment data block).
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 13 +++++++++++++
include/linux/nvmem-consumer.h | 1 +
2 files changed, 14 insertions(+)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_
}
EXPORT_SYMBOL_GPL(nvmem_dev_name);
+/**
+ * nvmem_dev_size() - Get the size of a given nvmem device.
+ *
+ * @nvmem: nvmem device.
+ *
+ * Return: size of the nvmem device.
+ */
+size_t nvmem_dev_size(struct nvmem_device *nvmem)
+{
+ return nvmem->size;
+}
+EXPORT_SYMBOL_GPL(nvmem_dev_size);
+
static int __init nvmem_init(void)
{
int ret;
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem
struct nvmem_cell_info *info, void *buf);
const char *nvmem_dev_name(struct nvmem_device *nvmem);
+size_t nvmem_dev_size(struct nvmem_device *nvmem);
void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
size_t nentries);

View File

@ -0,0 +1,126 @@
From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:18 +0100
Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem
helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simplify adding NVMEM cells.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 55 +++++++++++++++-----------------------
1 file changed, 21 insertions(+), 34 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -23,13 +23,10 @@ enum u_boot_env_format {
struct u_boot_env {
struct device *dev;
+ struct nvmem_device *nvmem;
enum u_boot_env_format format;
struct mtd_info *mtd;
-
- /* Cells */
- struct nvmem_cell_info *cells;
- int ncells;
};
struct u_boot_env_image_single {
@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_
static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
size_t data_offset, size_t data_len)
{
+ struct nvmem_device *nvmem = priv->nvmem;
struct device *dev = priv->dev;
char *data = buf + data_offset;
char *var, *value, *eq;
- int idx;
-
- priv->ncells = 0;
- for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
- priv->ncells++;
-
- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
- if (!priv->cells)
- return -ENOMEM;
- for (var = data, idx = 0;
+ for (var = data;
var < data + data_len && *var;
- var = value + strlen(value) + 1, idx++) {
+ var = value + strlen(value) + 1) {
+ struct nvmem_cell_info info = {};
+
eq = strchr(var, '=');
if (!eq)
break;
*eq = '\0';
value = eq + 1;
- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
- if (!priv->cells[idx].name)
+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+ if (!info.name)
return -ENOMEM;
- priv->cells[idx].offset = data_offset + value - data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
+ info.offset = data_offset + value - data;
+ info.bytes = strlen(value);
+ info.np = of_get_child_by_name(dev->of_node, info.name);
if (!strcmp(var, "ethaddr")) {
- priv->cells[idx].raw_len = strlen(value);
- priv->cells[idx].bytes = ETH_ALEN;
- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
+ info.raw_len = strlen(value);
+ info.bytes = ETH_ALEN;
+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
}
- }
- if (WARN_ON(idx != priv->ncells))
- priv->ncells = idx;
+ nvmem_add_one_cell(nvmem, &info);
+ }
return 0;
}
@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct u_boot_env *priv;
- int err;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf
return PTR_ERR(priv->mtd);
}
- err = u_boot_env_parse(priv);
- if (err)
- return err;
-
config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
config.priv = priv;
config.size = priv->mtd->size;
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
+ priv->nvmem = devm_nvmem_register(dev, &config);
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+ return u_boot_env_parse(priv);
}
static const struct of_device_id u_boot_env_of_match_table[] = {

View File

@ -0,0 +1,81 @@
From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:19 +0100
Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use nvmem_dev_size() and nvmem_device_read() to make this driver less
mtd dependent.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u
static int u_boot_env_parse(struct u_boot_env *priv)
{
+ struct nvmem_device *nvmem = priv->nvmem;
struct device *dev = priv->dev;
size_t crc32_data_offset;
size_t crc32_data_len;
size_t crc32_offset;
size_t data_offset;
size_t data_len;
+ size_t dev_size;
uint32_t crc32;
uint32_t calc;
- size_t bytes;
uint8_t *buf;
+ int bytes;
int err;
- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
+ dev_size = nvmem_dev_size(nvmem);
+
+ buf = kcalloc(1, dev_size, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
goto err_out;
}
- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
- dev_err(dev, "Failed to read from mtd: %d\n", err);
+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+ if (bytes < 0) {
+ err = bytes;
+ goto err_kfree;
+ } else if (bytes != dev_size) {
+ err = -EIO;
goto err_kfree;
}
@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo
break;
}
crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
- crc32_data_len = priv->mtd->size - crc32_data_offset;
- data_len = priv->mtd->size - data_offset;
+ crc32_data_len = dev_size - crc32_data_offset;
+ data_len = dev_size - data_offset;
calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
if (calc != crc32) {
@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo
goto err_kfree;
}
- buf[priv->mtd->size - 1] = '\0';
+ buf[dev_size - 1] = '\0';
err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
if (err)
dev_err(dev, "Failed to add cells: %d\n", err);

View File

@ -0,0 +1,62 @@
From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:20 +0100
Subject: [PATCH] nvmem: u-boot-env: improve coding style
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. Prefer kzalloc() over kcalloc()
See memory-allocation.rst which says: "to be on the safe side it's
best to use routines that set memory to zero, like kzalloc()"
2. Drop dev_err() for u_boot_env_add_cells() fail
It can fail only on -ENOMEM. We don't want to print error then.
3. Add extra "crc32_addr" variable
It makes code reading header's crc32 easier to understand / review.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo
size_t crc32_data_offset;
size_t crc32_data_len;
size_t crc32_offset;
+ __le32 *crc32_addr;
size_t data_offset;
size_t data_len;
size_t dev_size;
@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo
dev_size = nvmem_dev_size(nvmem);
- buf = kcalloc(1, dev_size, GFP_KERNEL);
+ buf = kzalloc(dev_size, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
goto err_out;
@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo
data_offset = offsetof(struct u_boot_env_image_broadcom, data);
break;
}
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
+ crc32_addr = (__le32 *)(buf + crc32_offset);
+ crc32 = le32_to_cpu(*crc32_addr);
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo
buf[dev_size - 1] = '\0';
err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
- if (err)
- dev_err(dev, "Failed to add cells: %d\n", err);
err_kfree:
kfree(buf);

View File

@ -0,0 +1,94 @@
From 401df0d4f4098ecc9c5278da2f50756d62e5b37d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 19 Dec 2023 13:01:03 +0100
Subject: [PATCH] nvmem: layouts: refactor .add_cells() callback arguments
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simply pass whole "struct nvmem_layout" instead of single variables.
There is nothing in "struct nvmem_layout" that we have to hide from
layout drivers. They also access it during .probe() and .remove().
Thanks to this change:
1. API gets more consistent
All layouts drivers callbacks get the same argument
2. Layouts get correct device
Before this change NVMEM core code was passing NVMEM device instead
of layout device. That resulted in:
* Confusing prints
* Calling devm_*() helpers on wrong device
* Helpers like of_device_get_match_data() dereferencing NULLs
3. It gets possible to get match data
First of all nvmem_layout_get_match_data() requires passing "struct
nvmem_layout" which .add_cells() callback didn't have before this. It
doesn't matter much as it's rather useless now anyway (and will be
dropped).
What's more important however is that of_device_get_match_data() can
be used now thanks to owning a proper device pointer.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20231219120104.3422-1-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 2 +-
drivers/nvmem/layouts/onie-tlv.c | 4 +++-
drivers/nvmem/layouts/sl28vpd.c | 4 +++-
include/linux/nvmem-provider.h | 2 +-
4 files changed, 8 insertions(+), 4 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -855,7 +855,7 @@ int nvmem_layout_register(struct nvmem_l
return -EINVAL;
/* Populate the cells */
- ret = layout->add_cells(&layout->nvmem->dev, layout->nvmem);
+ ret = layout->add_cells(layout);
if (ret)
return ret;
--- a/drivers/nvmem/layouts/onie-tlv.c
+++ b/drivers/nvmem/layouts/onie-tlv.c
@@ -182,8 +182,10 @@ static bool onie_tlv_crc_is_valid(struct
return true;
}
-static int onie_tlv_parse_table(struct device *dev, struct nvmem_device *nvmem)
+static int onie_tlv_parse_table(struct nvmem_layout *layout)
{
+ struct nvmem_device *nvmem = layout->nvmem;
+ struct device *dev = &layout->dev;
struct onie_tlv_hdr hdr;
size_t table_len, data_len, hdr_len;
u8 *table, *data;
--- a/drivers/nvmem/layouts/sl28vpd.c
+++ b/drivers/nvmem/layouts/sl28vpd.c
@@ -80,8 +80,10 @@ static int sl28vpd_v1_check_crc(struct d
return 0;
}
-static int sl28vpd_add_cells(struct device *dev, struct nvmem_device *nvmem)
+static int sl28vpd_add_cells(struct nvmem_layout *layout)
{
+ struct nvmem_device *nvmem = layout->nvmem;
+ struct device *dev = &layout->dev;
const struct nvmem_cell_info *pinfo;
struct nvmem_cell_info info = {0};
struct device_node *layout_np;
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -173,7 +173,7 @@ struct nvmem_cell_table {
struct nvmem_layout {
struct device dev;
struct nvmem_device *nvmem;
- int (*add_cells)(struct device *dev, struct nvmem_device *nvmem);
+ int (*add_cells)(struct nvmem_layout *layout);
};
struct nvmem_layout_driver {

View File

@ -0,0 +1,72 @@
From 43f60e3fb62edc7bd8891de8779fb422f4ae23ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Tue, 19 Dec 2023 13:01:04 +0100
Subject: [PATCH] nvmem: drop nvmem_layout_get_match_data()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Thanks for layouts refactoring we now have "struct device" associated
with layout. Also its OF pointer points directly to the "nvmem-layout"
DT node.
All it takes to get match data is a generic of_device_get_match_data().
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Michael Walle <michael@walle.cc>
Link: https://lore.kernel.org/r/20231219120104.3422-2-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 13 -------------
include/linux/nvmem-provider.h | 10 ----------
2 files changed, 23 deletions(-)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -877,19 +877,6 @@ void nvmem_layout_unregister(struct nvme
}
EXPORT_SYMBOL_GPL(nvmem_layout_unregister);
-const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
-{
- struct device_node __maybe_unused *layout_np;
- const struct of_device_id *match;
-
- layout_np = of_nvmem_layout_get_container(nvmem);
- match = of_match_node(layout->dev.driver->of_match_table, layout_np);
-
- return match ? match->data : NULL;
-}
-EXPORT_SYMBOL_GPL(nvmem_layout_get_match_data);
-
/**
* nvmem_register() - Register a nvmem device for given nvmem_config.
* Also creates a binary entry in /sys/bus/nvmem/devices/dev-name/nvmem
--- a/include/linux/nvmem-provider.h
+++ b/include/linux/nvmem-provider.h
@@ -205,9 +205,6 @@ void nvmem_layout_driver_unregister(stru
module_driver(__nvmem_layout_driver, nvmem_layout_driver_register, \
nvmem_layout_driver_unregister)
-const void *nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout);
-
#else
static inline struct nvmem_device *nvmem_register(const struct nvmem_config *c)
@@ -238,13 +235,6 @@ static inline int nvmem_layout_register(
static inline void nvmem_layout_unregister(struct nvmem_layout *layout) {}
-static inline const void *
-nvmem_layout_get_match_data(struct nvmem_device *nvmem,
- struct nvmem_layout *layout)
-{
- return NULL;
-}
-
#endif /* CONFIG_NVMEM */
#if IS_ENABLED(CONFIG_NVMEM) && IS_ENABLED(CONFIG_OF)

View File

@ -0,0 +1,53 @@
From 33cf42e68efc8ff529a7eee08a4f0ba8c8d0a207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:17 +0100
Subject: [PATCH] nvmem: core: add nvmem_dev_size() helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is required by layouts that need to read whole NVMEM content. It's
especially useful for NVMEM devices without hardcoded layout (like
U-Boot environment data block).
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-2-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/core.c | 13 +++++++++++++
include/linux/nvmem-consumer.h | 1 +
2 files changed, 14 insertions(+)
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -2164,6 +2164,19 @@ const char *nvmem_dev_name(struct nvmem_
}
EXPORT_SYMBOL_GPL(nvmem_dev_name);
+/**
+ * nvmem_dev_size() - Get the size of a given nvmem device.
+ *
+ * @nvmem: nvmem device.
+ *
+ * Return: size of the nvmem device.
+ */
+size_t nvmem_dev_size(struct nvmem_device *nvmem)
+{
+ return nvmem->size;
+}
+EXPORT_SYMBOL_GPL(nvmem_dev_size);
+
static int __init nvmem_init(void)
{
int ret;
--- a/include/linux/nvmem-consumer.h
+++ b/include/linux/nvmem-consumer.h
@@ -81,6 +81,7 @@ int nvmem_device_cell_write(struct nvmem
struct nvmem_cell_info *info, void *buf);
const char *nvmem_dev_name(struct nvmem_device *nvmem);
+size_t nvmem_dev_size(struct nvmem_device *nvmem);
void nvmem_add_cell_lookups(struct nvmem_cell_lookup *entries,
size_t nentries);

View File

@ -0,0 +1,126 @@
From 7c8979b42b1a9c5604f431ba804928e55919263c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:18 +0100
Subject: [PATCH] nvmem: u-boot-env: use nvmem_add_one_cell() nvmem subsystem
helper
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Simplify adding NVMEM cells.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-3-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 55 +++++++++++++++-----------------------
1 file changed, 21 insertions(+), 34 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -23,13 +23,10 @@ enum u_boot_env_format {
struct u_boot_env {
struct device *dev;
+ struct nvmem_device *nvmem;
enum u_boot_env_format format;
struct mtd_info *mtd;
-
- /* Cells */
- struct nvmem_cell_info *cells;
- int ncells;
};
struct u_boot_env_image_single {
@@ -94,43 +91,36 @@ static int u_boot_env_read_post_process_
static int u_boot_env_add_cells(struct u_boot_env *priv, uint8_t *buf,
size_t data_offset, size_t data_len)
{
+ struct nvmem_device *nvmem = priv->nvmem;
struct device *dev = priv->dev;
char *data = buf + data_offset;
char *var, *value, *eq;
- int idx;
-
- priv->ncells = 0;
- for (var = data; var < data + data_len && *var; var += strlen(var) + 1)
- priv->ncells++;
-
- priv->cells = devm_kcalloc(dev, priv->ncells, sizeof(*priv->cells), GFP_KERNEL);
- if (!priv->cells)
- return -ENOMEM;
- for (var = data, idx = 0;
+ for (var = data;
var < data + data_len && *var;
- var = value + strlen(value) + 1, idx++) {
+ var = value + strlen(value) + 1) {
+ struct nvmem_cell_info info = {};
+
eq = strchr(var, '=');
if (!eq)
break;
*eq = '\0';
value = eq + 1;
- priv->cells[idx].name = devm_kstrdup(dev, var, GFP_KERNEL);
- if (!priv->cells[idx].name)
+ info.name = devm_kstrdup(dev, var, GFP_KERNEL);
+ if (!info.name)
return -ENOMEM;
- priv->cells[idx].offset = data_offset + value - data;
- priv->cells[idx].bytes = strlen(value);
- priv->cells[idx].np = of_get_child_by_name(dev->of_node, priv->cells[idx].name);
+ info.offset = data_offset + value - data;
+ info.bytes = strlen(value);
+ info.np = of_get_child_by_name(dev->of_node, info.name);
if (!strcmp(var, "ethaddr")) {
- priv->cells[idx].raw_len = strlen(value);
- priv->cells[idx].bytes = ETH_ALEN;
- priv->cells[idx].read_post_process = u_boot_env_read_post_process_ethaddr;
+ info.raw_len = strlen(value);
+ info.bytes = ETH_ALEN;
+ info.read_post_process = u_boot_env_read_post_process_ethaddr;
}
- }
- if (WARN_ON(idx != priv->ncells))
- priv->ncells = idx;
+ nvmem_add_one_cell(nvmem, &info);
+ }
return 0;
}
@@ -209,7 +199,6 @@ static int u_boot_env_probe(struct platf
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct u_boot_env *priv;
- int err;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -224,17 +213,15 @@ static int u_boot_env_probe(struct platf
return PTR_ERR(priv->mtd);
}
- err = u_boot_env_parse(priv);
- if (err)
- return err;
-
config.dev = dev;
- config.cells = priv->cells;
- config.ncells = priv->ncells;
config.priv = priv;
config.size = priv->mtd->size;
- return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
+ priv->nvmem = devm_nvmem_register(dev, &config);
+ if (IS_ERR(priv->nvmem))
+ return PTR_ERR(priv->nvmem);
+
+ return u_boot_env_parse(priv);
}
static const struct of_device_id u_boot_env_of_match_table[] = {

View File

@ -0,0 +1,81 @@
From a832556d23c5a11115f300011a5874d6107a0d62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:19 +0100
Subject: [PATCH] nvmem: u-boot-env: use nvmem device helpers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Use nvmem_dev_size() and nvmem_device_read() to make this driver less
mtd dependent.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-4-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -127,27 +127,34 @@ static int u_boot_env_add_cells(struct u
static int u_boot_env_parse(struct u_boot_env *priv)
{
+ struct nvmem_device *nvmem = priv->nvmem;
struct device *dev = priv->dev;
size_t crc32_data_offset;
size_t crc32_data_len;
size_t crc32_offset;
size_t data_offset;
size_t data_len;
+ size_t dev_size;
uint32_t crc32;
uint32_t calc;
- size_t bytes;
uint8_t *buf;
+ int bytes;
int err;
- buf = kcalloc(1, priv->mtd->size, GFP_KERNEL);
+ dev_size = nvmem_dev_size(nvmem);
+
+ buf = kcalloc(1, dev_size, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
goto err_out;
}
- err = mtd_read(priv->mtd, 0, priv->mtd->size, &bytes, buf);
- if ((err && !mtd_is_bitflip(err)) || bytes != priv->mtd->size) {
- dev_err(dev, "Failed to read from mtd: %d\n", err);
+ bytes = nvmem_device_read(nvmem, 0, dev_size, buf);
+ if (bytes < 0) {
+ err = bytes;
+ goto err_kfree;
+ } else if (bytes != dev_size) {
+ err = -EIO;
goto err_kfree;
}
@@ -169,8 +176,8 @@ static int u_boot_env_parse(struct u_boo
break;
}
crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
- crc32_data_len = priv->mtd->size - crc32_data_offset;
- data_len = priv->mtd->size - data_offset;
+ crc32_data_len = dev_size - crc32_data_offset;
+ data_len = dev_size - data_offset;
calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
if (calc != crc32) {
@@ -179,7 +186,7 @@ static int u_boot_env_parse(struct u_boo
goto err_kfree;
}
- buf[priv->mtd->size - 1] = '\0';
+ buf[dev_size - 1] = '\0';
err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
if (err)
dev_err(dev, "Failed to add cells: %d\n", err);

View File

@ -0,0 +1,62 @@
From 6bafe07c930676d6430be471310958070816a595 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 21 Dec 2023 18:34:20 +0100
Subject: [PATCH] nvmem: u-boot-env: improve coding style
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. Prefer kzalloc() over kcalloc()
See memory-allocation.rst which says: "to be on the safe side it's
best to use routines that set memory to zero, like kzalloc()"
2. Drop dev_err() for u_boot_env_add_cells() fail
It can fail only on -ENOMEM. We don't want to print error then.
3. Add extra "crc32_addr" variable
It makes code reading header's crc32 easier to understand / review.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/r/20231221173421.13737-5-zajec5@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvmem/u-boot-env.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -132,6 +132,7 @@ static int u_boot_env_parse(struct u_boo
size_t crc32_data_offset;
size_t crc32_data_len;
size_t crc32_offset;
+ __le32 *crc32_addr;
size_t data_offset;
size_t data_len;
size_t dev_size;
@@ -143,7 +144,7 @@ static int u_boot_env_parse(struct u_boo
dev_size = nvmem_dev_size(nvmem);
- buf = kcalloc(1, dev_size, GFP_KERNEL);
+ buf = kzalloc(dev_size, GFP_KERNEL);
if (!buf) {
err = -ENOMEM;
goto err_out;
@@ -175,7 +176,8 @@ static int u_boot_env_parse(struct u_boo
data_offset = offsetof(struct u_boot_env_image_broadcom, data);
break;
}
- crc32 = le32_to_cpu(*(__le32 *)(buf + crc32_offset));
+ crc32_addr = (__le32 *)(buf + crc32_offset);
+ crc32 = le32_to_cpu(*crc32_addr);
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
@@ -188,8 +190,6 @@ static int u_boot_env_parse(struct u_boo
buf[dev_size - 1] = '\0';
err = u_boot_env_add_cells(priv, buf, data_offset, data_len);
- if (err)
- dev_err(dev, "Failed to add cells: %d\n", err);
err_kfree:
kfree(buf);

View File

@ -36,9 +36,9 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -182,7 +182,7 @@ static int u_boot_env_parse(struct u_boo
crc32_data_len = priv->mtd->size - crc32_data_offset;
data_len = priv->mtd->size - data_offset;
@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L);

View File

@ -36,9 +36,9 @@ Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
--- a/drivers/nvmem/u-boot-env.c
+++ b/drivers/nvmem/u-boot-env.c
@@ -182,7 +182,7 @@ static int u_boot_env_parse(struct u_boo
crc32_data_len = priv->mtd->size - crc32_data_offset;
data_len = priv->mtd->size - data_offset;
@@ -181,7 +181,7 @@ static int u_boot_env_parse(struct u_boo
crc32_data_len = dev_size - crc32_data_offset;
data_len = dev_size - data_offset;
- calc = crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L;
+ calc = le32_to_cpu((__le32)crc32(~0, buf + crc32_data_offset, crc32_data_len) ^ ~0L);