Re: [PATCH v5 00/21] nvmem: core: introduce NVMEM layouts

From: Michael Walle
Date: Thu Jan 05 2023 - 07:53:00 EST


Hi,

Am 2023-01-05 13:21, schrieb Alexander Stein:
Am Donnerstag, 5. Januar 2023, 13:11:37 CET schrieb Michael Walle:
thanks for debugging. I'm not yet sure what is going wrong, so
I have some more questions below.

>> This causes the following errors on existing boards (imx8mq-tqma8mq-
>> mba8mx.dtb):
>> root@tqma8-common:~# uname -r
>> 6.2.0-rc2-next-20230105
>>
>> > OF: /soc@0: could not get #nvmem-cell-cells for /soc@0/bus@30000000/
>>
>> efuse@30350000/soc-uid@4
>>
>> > OF: /soc@0/bus@30800000/ethernet@30be0000: could not get
>> > #nvmem-cell-cells
>>
>> for /soc@0/bus@30000000/efuse@30350000/mac-address@90
>>
>> These are caused because '#nvmem-cell-cells = <0>;' is not explicitly
>> set in
>> DT.
>>
>> > TI DP83867 30be0000.ethernet-1:0e: error -EINVAL: failed to get nvmem
>> > cell
>>
>> io_impedance_ctrl
>>
>> > TI DP83867: probe of 30be0000.ethernet-1:0e failed with error -22
>>
>> These are caused because of_nvmem_cell_get() now returns -EINVAL
>> instead of -
>> ENODEV if the requested nvmem cell is not available.

What do you mean with not available? Not yet available because of probe
order?

Ah, I was talking about there is no nvmem cell being used in my PHY node, e.g.
no 'nvmem-cells' nor 'nvmem-cell-names' (set to 'io_impedance_ctrl'). That's
why of_property_match_string returns -EINVAL.

Ahh I see. You mean ENOENT instead of ENODEV, right?

> Should we just assume #nvmem-cell-cells = <0> by default? I guess it's
> a safe assumption.

Actually, that's what patch 2/21 is for.

Alexander, did you verify that the EINVAL is returned by
of_parse_phandle_with_optional_args()?

Yep.

--8<--
diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 1b61c8bf0de4..f2a85a31d039 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1339,9 +1339,11 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node
*np, const char *id)
if (id)
index = of_property_match_string(np, "nvmem-cell-names", id);

+ pr_info("%s: index: %d\n", __func__, index);
ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
"#nvmem-cell-cells",
index, &cell_spec);
+ pr_info("%s: of_parse_phandle_with_optional_args: %d\n", __func__,
ret);
if (ret)
return ERR_PTR(ret);
--8<--

Results in:
[ 1.861896] of_nvmem_cell_get: index: -22
[ 1.865934] of_nvmem_cell_get: of_parse_phandle_with_optional_args: -22
[ 1.872595] TI DP83867 30be0000.ethernet-1:0e: error -EINVAL: failed to
get nvmem cell io_impedance_ctrl
[ 2.402575] TI DP83867: probe of 30be0000.ethernet-1:0e failed with error
-22

So, the index is wrong in the first place, but this was no problem until now.

Thanks, could you try the following patch:

diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c
index 1b61c8bf0de4..1085abfcd9b1 100644
--- a/drivers/nvmem/core.c
+++ b/drivers/nvmem/core.c
@@ -1336,8 +1336,11 @@ struct nvmem_cell *of_nvmem_cell_get(struct device_node *np, const char *id)
int ret;

/* if cell name exists, find index to the name */
- if (id)
+ if (id) {
index = of_property_match_string(np, "nvmem-cell-names", id);
+ if (index < 0)
+ return ERR_PTR(-ENOENT);
+ }

ret = of_parse_phandle_with_optional_args(np, "nvmem-cells",
"#nvmem-cell-cells",

Before patch 6/21, the -EINVAL was passed as index to of_parse_phandle()
which then returned NULL, which caused the nvmem core to return ENOENT.
I have a vague memory, that I made sure, that
of_parse_phandle_with_optional_args() will also propagate the
wrong index to its return code. But now, it won't be converted
to ENOENT.

-michael