Skip to content

Commit

Permalink
kernel: nvmem: fix "fixed-layout" & support "mac-base"
Browse files Browse the repository at this point in the history
DT binding for MAC cells in fixed layout was upstream approved and
accepted. Add support for it. This can replace quite some of our
downstream hacks.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
(cherry picked from commit 61f674d)
  • Loading branch information
Rafał Miłecki committed Nov 2, 2023
1 parent e465592 commit b649b0b
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 13 Jul 2023 17:30:59 +0200
Subject: [PATCH] nvmem: core: fix support for fixed cells NVMEM layout
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Returning -EPROBE_DEFER for "fixed-layout" makes nvmem_register() always
fail (that layout is supported internally with no external module). That
makes callers (e.g. mtd_nvmem_add()) fail as well and prevents booting
on devices with "fixed-layout" in DT.

Add a quick workaround for it.

Fixes: 6468a6f45148 ("nvmem: core: handle the absence of expected layouts")
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---

--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -794,6 +794,19 @@ static struct nvmem_layout *nvmem_layout
return NULL;

/*
+ * We should return -EPROBE_DEFER only when layout driver is expected to
+ * become available later. Otherwise NVMEM will never probe successfully
+ * for unsupported layouts. There is no known solution for that right
+ * now.
+ *
+ * This problem also affects "fixed-layout". It's supported in NVMEM
+ * core code so there never will be layout for it. We shouldn't return
+ * -EPROBE_DEFER in such case. Add a quick workaround for that.
+ */
+ if (of_device_is_compatible(layout_np, "fixed-layout"))
+ return NULL;
+
+ /*
* In case the nvmem device was built-in while the layout was built as a
* module, we shall manually request the layout driver loading otherwise
* we'll never have any match.
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Thu, 13 Jul 2023 18:29:19 +0200
Subject: [PATCH] nvmem: core: support "mac-base" fixed layout cells

Fixed layout binding allows specifying "mac-base" NVMEM cells. It's used
for base MAC address (that can be used for calculating relative
addresses). It can be stored in a raw binary format or as an ASCII
string.
---

--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig NVMEM
bool "NVMEM Support"
+ select GENERIC_NET_UTILS
help
Support for NVMEM(Non Volatile Memory) devices like EEPROM, EFUSES...

--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -7,9 +7,11 @@
*/

#include <linux/device.h>
+#include <linux/etherdevice.h>
#include <linux/export.h>
#include <linux/fs.h>
#include <linux/idr.h>
+#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/kref.h>
#include <linux/module.h>
@@ -696,6 +698,37 @@ static int nvmem_validate_keepouts(struc
return 0;
}

+static int nvmem_mac_base_raw_read(void *context, const char *id, int index, unsigned int offset,
+ void *buf, size_t bytes)
+{
+ if (WARN_ON(bytes != ETH_ALEN))
+ return -EINVAL;
+
+ if (index)
+ eth_addr_add(buf, index);
+
+ return 0;
+}
+
+static int nvmem_mac_base_ascii_read(void *context, const char *id, int index, unsigned int offset,
+ void *buf, size_t bytes)
+{
+ u8 mac[ETH_ALEN];
+
+ if (WARN_ON(bytes != 3 * ETH_ALEN - 1))
+ return -EINVAL;
+
+ if (!mac_pton(buf, mac))
+ return -EINVAL;
+
+ if (index)
+ eth_addr_add(mac, index);
+
+ ether_addr_copy(buf, mac);
+
+ return 0;
+}
+
static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
{
struct nvmem_layout *layout = nvmem->layout;
@@ -731,6 +764,20 @@ static int nvmem_add_cells_from_dt(struc
if (layout && layout->fixup_cell_info)
layout->fixup_cell_info(nvmem, layout, &info);

+ if (of_device_is_compatible(np, "fixed-layout")) {
+ if (of_device_is_compatible(child, "mac-base")) {
+ if (info.bytes == 6) {
+ info.raw_len = info.bytes;
+ info.bytes = ETH_ALEN;
+ info.read_post_process = nvmem_mac_base_raw_read;
+ } else if (info.bytes == 3 * ETH_ALEN - 1) {
+ info.raw_len = info.bytes;
+ info.bytes = ETH_ALEN;
+ info.read_post_process = nvmem_mac_base_ascii_read;
+ }
+ }
+ }
+
ret = nvmem_add_one_cell(nvmem, &info);
kfree(info.name);
if (ret) {

0 comments on commit b649b0b

Please sign in to comment.