6fa7b6382d8941c1d8b5937f97a6d49f21586355
[librecmc/librecmc.git] /
1 From 6468a6f45148fb5e95c86b4efebf63f9abcd2137 Mon Sep 17 00:00:00 2001
2 From: Miquel Raynal <miquel.raynal@bootlin.com>
3 Date: Tue, 4 Apr 2023 18:21:22 +0100
4 Subject: [PATCH] nvmem: core: handle the absence of expected layouts
5
6 Make nvmem_layout_get() return -EPROBE_DEFER while the expected layout
7 is not available. This condition cannot be triggered today as nvmem
8 layout drivers are initialed as part of an early init call, but soon
9 these drivers will be converted into modules and be initialized with a
10 standard priority, so the unavailability of the drivers might become a
11 reality that must be taken care of.
12
13 Let's anticipate this by telling the caller the layout might not yet be
14 available. A probe deferral is requested in this case.
15
16 Please note this does not affect any nvmem device not using layouts,
17 because an early check against the "nvmem-layout" container presence
18 will return NULL in this case.
19
20 Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
21 Tested-by: Michael Walle <michael@walle.cc>
22 Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
23 Link: https://lore.kernel.org/r/20230404172148.82422-15-srinivas.kandagatla@linaro.org
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
25 ---
26  drivers/nvmem/core.c | 10 +++++++++-
27  1 file changed, 9 insertions(+), 1 deletion(-)
28
29 --- a/drivers/nvmem/core.c
30 +++ b/drivers/nvmem/core.c
31 @@ -755,7 +755,7 @@ EXPORT_SYMBOL_GPL(nvmem_layout_unregiste
32  static struct nvmem_layout *nvmem_layout_get(struct nvmem_device *nvmem)
33  {
34         struct device_node *layout_np, *np = nvmem->dev.of_node;
35 -       struct nvmem_layout *l, *layout = NULL;
36 +       struct nvmem_layout *l, *layout = ERR_PTR(-EPROBE_DEFER);
37  
38         layout_np = of_get_child_by_name(np, "nvmem-layout");
39         if (!layout_np)
40 @@ -938,6 +938,13 @@ struct nvmem_device *nvmem_register(cons
41          * pointer will be NULL and nvmem_layout_put() will be a noop.
42          */
43         nvmem->layout = config->layout ?: nvmem_layout_get(nvmem);
44 +       if (IS_ERR(nvmem->layout)) {
45 +               rval = PTR_ERR(nvmem->layout);
46 +               nvmem->layout = NULL;
47 +
48 +               if (rval == -EPROBE_DEFER)
49 +                       goto err_teardown_compat;
50 +       }
51  
52         if (config->cells) {
53                 rval = nvmem_add_cells(nvmem, config->cells, config->ncells);
54 @@ -970,6 +977,7 @@ struct nvmem_device *nvmem_register(cons
55  err_remove_cells:
56         nvmem_device_remove_all_cells(nvmem);
57         nvmem_layout_put(nvmem->layout);
58 +err_teardown_compat:
59         if (config->compat)
60                 nvmem_sysfs_remove_compat(nvmem, config);
61  err_put_device: