kernel: backport NVMEM patches queued for the v6.4
[openwrt/openwrt.git] / target / linux / generic / backport-5.10 / 814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
diff --git a/target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch b/target/linux/generic/backport-5.10/814-v6.4-0003-nvmem-core-handle-the-absence-of-expected-layouts.patch
new file mode 100644 (file)
index 0000000..6fa7b63
--- /dev/null
@@ -0,0 +1,61 @@
+From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001
+From: Miquel Raynal <miquel.raynal@bootlin.com>
+Date: Tue, 4 Apr 2023 18:21:22 +0100
+Subject: [PATCH] nvmem: core: handle the absence of expected layouts
+
+Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout
+is not available. This condition cannot be triggered today as nvmem
+layout drivers are initialed as part of an early init call, but soon
+these drivers will be converted into modules and be initialized with a
+standard priority, so the unavailability of the drivers might become a
+reality that must be taken care of.
+
+Let's anticipate this by telling the caller the layout might not yet be
+available. A probe deferral is requested in this case.
+
+Please note this does not affect any nvmem device not using layouts,
+because an early check against the "nvmem-layout" container presence
+will return NULL in this case.
+
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+Tested-by: Michael Walle <michael@walle.cc>
+Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/nvmem/core.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/nvmem/core.c
++++ b/drivers/nvmem/core.c
+@@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
+ static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
+ {
+       struct device_node *layout_np, *np = nvmem->dev.of_node;
+-      struct nvmem_layout *l, *layout = NULL;
++      struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
+       layout_np = of_get_child_by_name(np, "nvmem-layout");
+       if (!layout_np)
+@@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons
+        * pointer will be NULL and nvmem_layout_put() will be a noop.
+        */
+       nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
++      if (IS_ERR(nvmem->layout)) {
++              rval = PTR_ERR(nvmem->layout);
++              nvmem->layout = NULL;
++
++              if (rval == -EPROBE_DEFER)
++                      goto err_teardown_compat;
++      }
+       if (config->cells) {
+               rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
+@@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons
+ err_remove_cells:
+       nvmem_device_remove_all_cells(nvmem);
+       nvmem_layout_put(nvmem->layout);
++err_teardown_compat:
+       if (config->compat)
+               nvmem_sysfs_remove_compat(nvmem, config);
+ err_put_device: