forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
kernel: nvmem: fix "fixed-layout" & support "mac-base"
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
Showing
2 changed files
with
133 additions
and
0 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
.../linux/generic/pending-5.15/803-nvmem-core-fix-support-for-fixed-cells-NVMEM-layout.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
93 changes: 93 additions & 0 deletions
93
target/linux/generic/pending-5.15/804-nvmem-core-support-mac-base-fixed-layout-cells.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) { |