Skip to contentSkip to conversation

nvmem: add fixed cells layout

PATCH Superseded Rafał Miłecki 3 participants 7 messages Mar 21, 2023 – Mar 27, 2023

Subsystems (2)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v5 cover nvmem: add fixed cells layout

From: Rafał Miłecki <[email protected]>

NVMEM bindings received a new feature recently: layouts. They allow defining NVMEM device content in a separated DT node named "nvmem-layout". That improvement results in cleaner and more generic bindings.

New bindings & drivers should use layouts design. If possible we should also try converting existing bindings & drivers to layouts.

This patchset allows defining NVMEM cells in a new way (using NVMEM layout feature).

This deprecates support for defining NVMEM cells as direct DT device node subnodes but IT DOESN'T drop support for that.

PLEASE understand what this patchset handles. It adds new & preferred way of defining NVMEM cells. This patchset does NOT meant to:
1. Convert ALL existing bindings or drivers (it's a task for later)
2. Add support for new extra features (like multiple layouts)
3. Break any backward compatibility (it WON'T happen)

V5:
Support "fixed-layout" internally in NVMEM core (see PATCH 3/3)

Rafał Miłecki (3):
dt-bindings: nvmem: layouts: add fixed-layout
dt-bindings: nvmem: convert base example to use NVMEM fixed cells
layout
nvmem: core: add support for fixed cells *layout*

 .../bindings/nvmem/layouts/fixed-cell.yaml    | 31 ++++++++++
 .../bindings/nvmem/layouts/fixed-layout.yaml  | 49 +++++++++++++++
 .../bindings/nvmem/layouts/nvmem-layout.yaml  |  5 +-
 .../devicetree/bindings/nvmem/nvmem.yaml      | 61 ++++++++-----------
 drivers/nvmem/core.c                          | 32 +++++++++-
 5 files changed, 136 insertions(+), 42 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml
Signature · 1 line
2.34.1
#1 lore raw

PATCH v5 1/3 dt-bindings: nvmem: layouts: add fixed-layout

From: Rafał Miłecki <[email protected]>

With the introduction of NVMEM layouts, new NVMEM content structures should be defined as such. We should also try to convert / migrate existing NVMEM content bindings to layouts.

This commit handles fixed NVMEM cells. So far they had to be defined directly - as device subnodes. With this change it's allowed to put them in the DT node named "nvmem-layout".

Having NVMEM cells in separated node is preferred as it draws a nice line between NVMEM device and its content. It results in cleaner bindings.

FWIW a very similar situation has happened to MTD devices and their
partitions: see commit 5d96ea42eb63 ("dt-bindings: mtd: Clarify all partition subnodes").

---
 .../bindings/nvmem/layouts/fixed-cell.yaml    | 31 ++++++++++++
 .../bindings/nvmem/layouts/fixed-layout.yaml  | 49 +++++++++++++++++++
 .../bindings/nvmem/layouts/nvmem-layout.yaml  |  5 +-
 .../devicetree/bindings/nvmem/nvmem.yaml      | 19 +------
 4 files changed, 83 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml
Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml new file +31 -0
new file mode 100644
index 000000000000..e698098450e1
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/layouts/fixed-cell.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Fixed offset & size NVMEM cell
+
+maintainers:
+  - Rafał Miłecki <[email protected]>
+  - Srinivas Kandagatla <[email protected]>
+
+properties:
+  reg:
+    maxItems: 1
+
+  bits:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    items:
+      - minimum: 0
+        maximum: 7
+        description:
+          Offset in bit within the address range specified by reg.
+      - minimum: 1
+        description:
+          Size in bit within the address range specified by reg.
+
+required:
+  - reg
+
+additionalProperties: true
Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml new file +49 -0

49 lines not on this page · raw message

Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml +1 -4
index 8512ee538c4c..3b40f7880774 100644
@@ -18,16 +18,13 @@ description: |
   perform their parsing. The nvmem-layout container is here to describe these.
 
 oneOf:
+  - $ref: fixed-layout.yaml
   - $ref: kontron,sl28-vpd.yaml
   - $ref: onie,tlv-layout.yaml
 
 properties:
   compatible: true
 
-  '#address-cells': false
-
-  '#size-cells': false
-
 required:
   - compatible
 
Documentation/devicetree/bindings/nvmem/nvmem.yaml +2 -17
index 75bb93dda9df..b79f1bb795fb 100644
@@ -49,23 +49,8 @@ properties:
 patternProperties:
   "@[0-9a-f]+(,[0-7])?$":
     type: object
-
-    properties:
-      reg:
-        maxItems: 1
-        description:
-          Offset and size in bytes within the storage device.
-
-      bits:
-        $ref: /schemas/types.yaml#/definitions/uint32-array
-        items:
-          - minimum: 0
-            maximum: 7
-            description:
-              Offset in bit within the address range specified by reg.
-          - minimum: 1
-            description:
-              Size in bit within the address range specified by reg.
+    $ref: layouts/fixed-cell.yaml
+    deprecated: true
 
 additionalProperties: true
 
Signature · 1 line
2.34.1
maintainer
#2 lore raw

Re: [PATCH V5 1/3] dt-bindings: nvmem: layouts: add fixed-layout

Quoted 93 lines · Rafał Miłecki

From: Rafał Miłecki <[email protected]>

With the introduction of NVMEM layouts, new NVMEM content structures should be defined as such. We should also try to convert / migrate existing NVMEM content bindings to layouts.

This commit handles fixed NVMEM cells. So far they had to be defined directly - as device subnodes. With this change it's allowed to put them in the DT node named "nvmem-layout".

Having NVMEM cells in separated node is preferred as it draws a nice line between NVMEM device and its content. It results in cleaner bindings.

FWIW a very similar situation has happened to MTD devices and their
partitions: see commit 5d96ea42eb63 ("dt-bindings: mtd: Clarify all partition subnodes").

---
 .../bindings/nvmem/layouts/fixed-cell.yaml    | 31 ++++++++++++
 .../bindings/nvmem/layouts/fixed-layout.yaml  | 49 +++++++++++++++++++
 .../bindings/nvmem/layouts/nvmem-layout.yaml  |  5 +-
 .../devicetree/bindings/nvmem/nvmem.yaml      | 19 +------
 4 files changed, 83 insertions(+), 21 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml
 create mode 100644 Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml
Documentation/devicetree/bindings/nvmem/layouts/fixed-cell.yaml new file +31 -0
new file mode 100644
index 000000000000..e698098450e1
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/layouts/fixed-cell.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Fixed offset & size NVMEM cell
+
+maintainers:
+  - Rafał Miłecki <[email protected]>
+  - Srinivas Kandagatla <[email protected]>
+
+properties:
+  reg:
+    maxItems: 1
+
+  bits:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    items:
+      - minimum: 0
+        maximum: 7
+        description:
+          Offset in bit within the address range specified by reg.
+      - minimum: 1
+        description:
+          Size in bit within the address range specified by reg.
+
+required:
+  - reg
+
+additionalProperties: true
Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml new file +22 -0
new file mode 100644
index 000000000000..f7496ba28f33
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/layouts/fixed-layout.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVMEM layout for fixed NVMEM cells
+
+description:
+  Many NVMEM devices have hardcoded cells layout (offset and size of defined
+  NVMEM content doesn't change).
+
+  This binding allows defining such NVMEM layout with its cells. It can be used
+  on top of any NVMEM device.
+
+maintainers:
+  - Rafał Miłecki <[email protected]>
+
+properties:
+  compatible:
+    const: fixed-layout
+

Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml line 32

Quoted 10 lines
Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml new file +10 -0
+  "#address-cells":
+    const: 1
+
+  "#size-cells":
+    const: 1
+
+patternProperties:
+  "@[a-f0-9]+$":
+    type: object
+    $ref: fixed-cell.yaml

This $ref allows additional properties, so here you need 'unevaluatedProperties: false'. Or restrict fixed-cell.yaml.

Quoted 72 lines
Documentation/devicetree/bindings/nvmem/layouts/fixed-layout.yaml new file +17 -0
+
+required:
+  - compatible
+
+additionalProperties: false
+
+examples:
+  - |
+    nvmem-layout {
+        compatible = "fixed-layout";
+        #address-cells = <1>;
+        #size-cells = <1>;
+
+        calibration@4000 {
+            reg = <0x4000 0x100>;
+        };
+    };
Documentation/devicetree/bindings/nvmem/layouts/nvmem-layout.yaml +1 -4
index 8512ee538c4c..3b40f7880774 100644
@@ -18,16 +18,13 @@ description: |
   perform their parsing. The nvmem-layout container is here to describe these.
 
 oneOf:
+  - $ref: fixed-layout.yaml
   - $ref: kontron,sl28-vpd.yaml
   - $ref: onie,tlv-layout.yaml
 
 properties:
   compatible: true
 
-  '#address-cells': false
-
-  '#size-cells': false
-
 required:
   - compatible
 
Documentation/devicetree/bindings/nvmem/nvmem.yaml +2 -17
index 75bb93dda9df..b79f1bb795fb 100644
@@ -49,23 +49,8 @@ properties:
 patternProperties:
   "@[0-9a-f]+(,[0-7])?$":
     type: object
-
-    properties:
-      reg:
-        maxItems: 1
-        description:
-          Offset and size in bytes within the storage device.
-
-      bits:
-        $ref: /schemas/types.yaml#/definitions/uint32-array
-        items:
-          - minimum: 0
-            maximum: 7
-            description:
-              Offset in bit within the address range specified by reg.
-          - minimum: 1
-            description:
-              Size in bit within the address range specified by reg.
+    $ref: layouts/fixed-cell.yaml
+    deprecated: true
 
 additionalProperties: true
 
Signature · 1 line
2.34.1
#3 lore raw

PATCH v5 2/3 dt-bindings: nvmem: convert base example to use NVMEM fixed cells layout

In reply to Rafał Miłecki

From: Rafał Miłecki <[email protected]>

With support for the "fixed-layout" binding it's possible and preferred now to define fixed NVMEM cells in the layout node. Do that for the example binding.

---
 .../devicetree/bindings/nvmem/nvmem.yaml      | 42 +++++++++++--------
 1 file changed, 24 insertions(+), 18 deletions(-)
Documentation/devicetree/bindings/nvmem/nvmem.yaml +24 -18
index b79f1bb795fb..980244100690 100644
@@ -68,24 +68,30 @@ examples:
 
           /* ... */
 
-          /* Data cells */
-          tsens_calibration: calib@404 {
-              reg = <0x404 0x10>;
-          };
-
-          tsens_calibration_bckp: calib_bckp@504 {
-              reg = <0x504 0x11>;
-              bits = <6 128>;
-          };
-
-          pvs_version: pvs-version@6 {
-              reg = <0x6 0x2>;
-              bits = <7 2>;
-          };
-
-          speed_bin: speed-bin@c{
-              reg = <0xc 0x1>;
-              bits = <2 3>;
+          nvmem-layout {
+              compatible = "fixed-layout";
+              #address-cells = <1>;
+              #size-cells = <1>;
+
+              /* Data cells */
+              tsens_calibration: calib@404 {
+                  reg = <0x404 0x10>;
+              };
+
+              tsens_calibration_bckp: calib_bckp@504 {
+                  reg = <0x504 0x11>;
+                  bits = <6 128>;
+              };
+
+              pvs_version: pvs-version@6 {
+                  reg = <0x6 0x2>;
+                  bits = <7 2>;
+              };
+
+              speed_bin: speed-bin@c{
+                  reg = <0xc 0x1>;
+                  bits = <2 3>;
+              };
           };
       };
 
Signature · 1 line
2.34.1
maintainer Reviewed-by on v5 2/3
#4 lore raw

Re: [PATCH V5 2/3] dt-bindings: nvmem: convert base example to use NVMEM fixed cells layout

Quoted 11 lines · Rafał Miłecki

From: Rafał Miłecki <[email protected]>

With support for the "fixed-layout" binding it's possible and preferred now to define fixed NVMEM cells in the layout node. Do that for the example binding.

---
 .../devicetree/bindings/nvmem/nvmem.yaml      | 42 +++++++++++--------
 1 file changed, 24 insertions(+), 18 deletions(-)
#5 lore raw

PATCH v5 3/3 nvmem: core: add support for fixed cells *layout*

In reply to Rafał Miłecki

From: Rafał Miłecki <[email protected]>

This adds support for the "fixed-layout" NVMEM layout binding. It allows defining NVMEM cells in a layout DT node named "nvmem-layout".

While NVMEM subsystem supports layout drivers it has been discussed that "fixed-layout" may actually be supperted internally. It's because:
1. It's a very basic layout
2. It allows sharing code with legacy syntax parsing
3. It's safer for soc_device_match() due to -EPROBE_DEFER
4. This will make the syntax transition easier

---
 drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)
drivers/nvmem/core.c +29 -3
index 212c5ba5789f..591b640f53dd 100644
@@ -694,7 +694,7 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem)
 	return 0;
 }
 
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np)
 {
 	struct nvmem_layout *layout = nvmem->layout;
 	struct device *dev = &nvmem->dev;
@@ -702,7 +702,7 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 	const __be32 *addr;
 	int len, ret;
 
-	for_each_child_of_node(dev->of_node, child) {
+	for_each_child_of_node(np, child) {
 		struct nvmem_cell_info info = {0};
 
 		addr = of_get_property(child, "reg", &len);
@@ -740,6 +740,28 @@ static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
 	return 0;
 }
 
+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
+{
+	return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
+}
+
+static int nvmem_add_cells_fixed(struct nvmem_device *nvmem)
+{
+	struct device_node *layout_np;
+	int err = 0;
+
+	layout_np = of_nvmem_layout_get_container(nvmem);
+	if (!layout_np)
+		return 0;
+
+	if (of_device_is_compatible(layout_np, "fixed-layout"))
+		err = nvmem_add_cells_from_dt(nvmem, layout_np);
+
+	of_node_put(layout_np);
+
+	return err;
+}
+
 int __nvmem_layout_register(struct nvmem_layout *layout, struct module *owner)
 {
 	layout->owner = owner;
@@ -970,7 +992,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
-	rval = nvmem_add_cells_from_of(nvmem);
+	rval = nvmem_add_cells_from_legacy_of(nvmem);
 	if (rval)
 		goto err_remove_cells;
 
@@ -980,6 +1002,10 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
+	rval = nvmem_add_cells_fixed(nvmem);
+	if (rval)
+		goto err_remove_cells;
+
 	rval = nvmem_add_cells_from_layout(nvmem);
 	if (rval)
 		goto err_remove_cells;
Signature · 1 line
2.34.1
Reviewed-by on v5 3/3
#6 lore raw

Re: [PATCH V5 3/3] nvmem: core: add support for fixed cells *layout*

Am 2023-03-21 11:24, schrieb Rafał Miłecki:

Quoted 84 lines

From: Rafał Miłecki <[email protected]>

This adds support for the "fixed-layout" NVMEM layout binding. It allows defining NVMEM cells in a layout DT node named "nvmem-layout".

While NVMEM subsystem supports layout drivers it has been discussed that "fixed-layout" may actually be supperted internally. It's because:
1. It's a very basic layout
2. It allows sharing code with legacy syntax parsing
3. It's safer for soc_device_match() due to -EPROBE_DEFER
4. This will make the syntax transition easier

---
 drivers/nvmem/core.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)
drivers/nvmem/core.c +1 -1
index 212c5ba5789f..591b640f53dd 100644
@@ -694,7 +694,7 @@ static int nvmem_validate_keepouts(struct
 nvmem_device *nvmem)
 	return 0;
 }
 
-static int nvmem_add_cells_from_of(struct nvmem_device *nvmem)
+static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct
 device_node *np)
 {
drivers/nvmem/core.c +1 -1
 	struct nvmem_layout *layout = nvmem->layout;
 	struct device *dev = &nvmem->dev;
@@ -702,7 +702,7 @@ static int nvmem_add_cells_from_of(struct
 nvmem_device *nvmem)
 	const __be32 *addr;
 	int len, ret;
 
-	for_each_child_of_node(dev->of_node, child) {
+	for_each_child_of_node(np, child) {
 		struct nvmem_cell_info info = {0};
 
drivers/nvmem/core.c +22 -0
 		addr = of_get_property(child, "reg", &len);
@@ -740,6 +740,28 @@ static int nvmem_add_cells_from_of(struct
 nvmem_device *nvmem)
 	return 0;
 }
 
+static int nvmem_add_cells_from_legacy_of(struct nvmem_device *nvmem)
+{
+	return nvmem_add_cells_from_dt(nvmem, nvmem->dev.of_node);
+}
+
+static int nvmem_add_cells_fixed(struct nvmem_device *nvmem)
+{
+	struct device_node *layout_np;
+	int err = 0;
+
+	layout_np = of_nvmem_layout_get_container(nvmem);
+	if (!layout_np)
+		return 0;
+
+	if (of_device_is_compatible(layout_np, "fixed-layout"))
+		err = nvmem_add_cells_from_dt(nvmem, layout_np);
+
+	of_node_put(layout_np);
+
+	return err;
+}
+
 int __nvmem_layout_register(struct nvmem_layout *layout, struct module 
 *owner)

{

drivers/nvmem/core.c +1 -1
 	layout->owner = owner;
@@ -970,7 +992,7 @@ struct nvmem_device *nvmem_register(const struct
 nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
-	rval = nvmem_add_cells_from_of(nvmem);
+	rval = nvmem_add_cells_from_legacy_of(nvmem);
 	if (rval)
 		goto err_remove_cells;

drivers/nvmem/core.c struct nvmem_device *nvmem_register(const struct · line 1006

Quoted 5 lines
drivers/nvmem/core.c +1 -0
@@ -980,6 +1002,10 @@ struct nvmem_device *nvmem_register(const struct
 nvmem_config *config)
 	if (rval)
 		goto err_remove_cells;
 
+	rval = nvmem_add_cells_fixed(nvmem);

nvmem_add_cells_from_fixed_layout()?

Quoted 6 lines
drivers/nvmem/core.c +3 -0
+	if (rval)
+		goto err_remove_cells;
+
 	rval = nvmem_add_cells_from_layout(nvmem);
 	if (rval)

goto err_remove_cells;