2021-04-27 08:28:08

by Nandor Han

[permalink] [raw]
Subject: [PATCH 0/4] Bootcount driver using NVMEM cell as backend.

Description
-----------
Implement a bootcount (1) related driver that uses
NVMEM as a backend. The patchset will also update the
`snvs_lpgpr` driver to support 2 bytes NVMEM cells.

1. https://www.denx.de/wiki/view/DULG/UBootBootCountLimit

Testing
-------
Hardware: i.MX6sx evaluation board
Kernel: linux-imx-5.4.24

1. Configure the bootcount hardware in DT to use a NVMEM cell provided
by `snvs_lpgpr` driver as backend.
e.g. This will configure a 4 bytes long NVMEM cell
```
bootcount_regs: bootcount-snvs-regs@0 {
reg = <0x0 0x04>;
};
```

2. Record the current NVMEM cell content:
```
~ # hexdump -C
/sys/devices/soc0/soc/2000000.aips-bus/20cc000.snvs/20cc000.snvs:snvs-lpgpr/20cc000.snvs:snvs-lpgpr0/nvmem
00000000 00 00 01 b0 |....|
00000004
```

3. Write the bootcount and check that is successful: PASS
```
~ # echo 1 > /sys/bus/platform/drivers/bootcount-nvmem/bootcount/value
bootcount: Write regval: 0xb0010001
~ # hexdump -C
/sys/devices/soc0/soc/2000000.aips-bus/20cc000.snvs/20cc000.snvs:snvs-lpgpr/20cc000.snvs:snvs-lpgpr0/nvmem
00000000 01 00 01 b0 |....|
00000004
```

Note: similar tests were done also for 2 bytes NVMEM cell size.

Kernel: linux-next, tag: next-20210322
1. Enable bootcount and snvs_lpgpr drivers
2. Verify that they compile succesfully: PASS
```
kernel-master> make -j2 drivers/nvmem/
DESCEND objtool
CALL scripts/atomic/check-atomics.sh
CC arch/x86/kernel/asm-offsets.s
CALL scripts/checksyscalls.sh
CC drivers/nvmem/core.o
CC drivers/nvmem/bootcount-nvmem.o
CC drivers/nvmem/snvs_lpgpr.o
AR drivers/nvmem/built-in.
```


Nandor Han (4):
dt-bindings: nvmem: Add bootcount-nvmem
nvmem: bootcount: add bootcount driver
nvmem: snvs_lpgpr: use cell stride for regmap size calculation
nvmem: snvs_lpgpr: support two bytes NVMEM cell size

.../bindings/nvmem/bootcount-nvmem.yaml | 72 +++++++
drivers/nvmem/Kconfig | 10 +
drivers/nvmem/Makefile | 1 +
drivers/nvmem/bootcount-nvmem.c | 195 ++++++++++++++++++
drivers/nvmem/snvs_lpgpr.c | 67 +++++-
5 files changed, 339 insertions(+), 6 deletions(-)
create mode 100644 Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml
create mode 100644 drivers/nvmem/bootcount-nvmem.c

--
2.26.3


2021-04-27 08:28:16

by Nandor Han

[permalink] [raw]
Subject: [PATCH 2/4] nvmem: bootcount: add bootcount driver

In order to have a robust system we want to be able to identify and take
actions if a boot loop occurs. This is possible by using the bootcount
feature, which can be used to identify the number of times device has
booted since bootcount was last time reset. Bootcount feature (1)
requires a collaboration between bootloader and user-space, where
the bootloader will increase a counter and user-space reset it.
If the counter is not reset and a pre-established threshold is reached,
bootloader can react and take action.

This is the kernel side implementation, which can be used to
identify the number of times device has booted since bootcount was
last time reset.

The driver supports both 16 and 32 bits NVMEM cell size.

1) https://www.denx.de/wiki/DULG/UBootBootCountLimit

Signed-off-by: Vesa Jääskeläinen <[email protected]>
Signed-off-by: Tomas Melin <[email protected]>
Signed-off-by: Nandor Han <[email protected]>
---
drivers/nvmem/Kconfig | 10 ++
drivers/nvmem/Makefile | 1 +
drivers/nvmem/bootcount-nvmem.c | 195 ++++++++++++++++++++++++++++++++
3 files changed, 206 insertions(+)
create mode 100644 drivers/nvmem/bootcount-nvmem.c

diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig
index dd2019006838..d5413c937350 100644
--- a/drivers/nvmem/Kconfig
+++ b/drivers/nvmem/Kconfig
@@ -288,4 +288,14 @@ config NVMEM_BRCM_NVRAM
This driver provides support for Broadcom's NVRAM that can be accessed
using I/O mapping.

+config BOOTCOUNT_NVMEM
+ bool "Bootcount driver using nvmem registers"
+ depends on OF
+ depends on NVMEM
+ help
+ Driver that implements the bootcount feature support using a
+ NVMEM cell as a backend. The driver supports 2 and 4 bytes
+ size cells.
+
+ Say y here to enable bootcount support.
endif
diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
index bbea1410240a..4c77679bbf0d 100644
--- a/drivers/nvmem/Makefile
+++ b/drivers/nvmem/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_NVMEM_RMEM) += nvmem-rmem.o
nvmem-rmem-y := rmem.o
obj-$(CONFIG_NVMEM_BRCM_NVRAM) += nvmem_brcm_nvram.o
nvmem_brcm_nvram-y := brcm_nvram.o
+obj-$(CONFIG_BOOTCOUNT_NVMEM) += bootcount-nvmem.o
diff --git a/drivers/nvmem/bootcount-nvmem.c b/drivers/nvmem/bootcount-nvmem.c
new file mode 100644
index 000000000000..7d9b6caefc2b
--- /dev/null
+++ b/drivers/nvmem/bootcount-nvmem.c
@@ -0,0 +1,195 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) Vaisala Oyj. All rights reserved.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* Default magic values from u-boot bootcount drivers */
+#define BOOTCOUNT_NVMEM_DEFAULT_MAGIC_VAL16 0xBC00
+#define BOOTCOUNT_NVMEM_DEFAULT_MAGIC_VAL32 0xB001C041
+
+struct bootcount_nvmem {
+ struct nvmem_cell *nvmem;
+ u32 magic;
+ u32 mask;
+ size_t bytes_count;
+};
+
+static ssize_t value_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct bootcount_nvmem *bootcount = dev_get_drvdata(dev);
+ u32 regval;
+ int ret;
+
+ ret = kstrtou32(buf, 0, &regval);
+ if (ret < 0)
+ return ret;
+
+ /* Check if the value fits */
+ if ((regval & ~(bootcount->mask)) != 0)
+ return -EINVAL;
+
+ /*
+ * In case we use 2 bytes for saving the value we need to take
+ * in consideration the endianness of the system. Because of this
+ * we mirror the 2 bytes from one side to another.
+ * This way, regardless of endianness, the value will be written
+ * in the correct order.
+ */
+ if (bootcount->bytes_count == 2) {
+ regval &= 0xffff;
+ regval |= (regval & 0xffff) << 16;
+ }
+
+ regval = (~bootcount->mask & bootcount->magic) |
+ (regval & bootcount->mask);
+ ret = nvmem_cell_write(bootcount->nvmem, &regval,
+ bootcount->bytes_count);
+ if (ret < 0)
+ return ret;
+ else if (ret != bootcount->bytes_count)
+ ret = -EIO;
+ else
+ ret = count;
+
+ return ret;
+}
+
+static ssize_t value_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct bootcount_nvmem *bootcount = dev_get_drvdata(dev);
+ u32 regval;
+ void *val;
+ size_t len;
+ int ret;
+
+ val = nvmem_cell_read(bootcount->nvmem, &len);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+
+ if (len != bootcount->bytes_count) {
+ kfree(val);
+ return -EINVAL;
+ }
+
+ if (bootcount->bytes_count == 2)
+ regval = *(u16 *)val;
+ else
+ regval = *(u32 *)val;
+
+ kfree(val);
+
+ if ((regval & ~bootcount->mask) == bootcount->magic)
+ ret = scnprintf(buf, PAGE_SIZE, "%u\n",
+ (unsigned int)(regval & bootcount->mask));
+ else {
+ dev_warn(dev, "invalid magic value\n");
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static DEVICE_ATTR_RW(value);
+
+static int bootcount_nvmem_probe(struct platform_device *pdev)
+{
+ struct bootcount_nvmem *bootcount;
+ int ret;
+ u32 bits;
+ void *val = NULL;
+ size_t len;
+
+ bootcount = devm_kzalloc(&pdev->dev, sizeof(struct bootcount_nvmem),
+ GFP_KERNEL);
+ if (!bootcount)
+ return -ENOMEM;
+
+ bootcount->nvmem = devm_nvmem_cell_get(&pdev->dev, "bootcount-regs");
+ if (IS_ERR(bootcount->nvmem)) {
+ if (PTR_ERR(bootcount->nvmem) != -EPROBE_DEFER)
+ dev_err(&pdev->dev, "cannot get 'bootcount-regs'\n");
+ return PTR_ERR(bootcount->nvmem);
+ }
+
+ /* detect cell dimensions */
+ val = nvmem_cell_read(bootcount->nvmem, &len);
+ if (IS_ERR(val))
+ return PTR_ERR(val);
+ kfree(val);
+ val = NULL;
+
+ if (len != 2 && len != 4) {
+ dev_err(&pdev->dev, "unsupported register size\n");
+ return -EINVAL;
+ }
+
+ bootcount->bytes_count = len;
+
+ platform_set_drvdata(pdev, bootcount);
+
+ ret = device_create_file(&pdev->dev, &dev_attr_value);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to export bootcount value\n");
+ return ret;
+ }
+
+ bits = bootcount->bytes_count << 3;
+ bootcount->mask = GENMASK((bits >> 1) - 1, 0);
+
+ ret = of_property_read_u32(pdev->dev.of_node, "linux,bootcount-magic",
+ &bootcount->magic);
+ if (ret == -EINVAL) {
+ if (bootcount->bytes_count == 2)
+ bootcount->magic = BOOTCOUNT_NVMEM_DEFAULT_MAGIC_VAL16;
+ else
+ bootcount->magic = BOOTCOUNT_NVMEM_DEFAULT_MAGIC_VAL32;
+ ret = 0;
+ } else if (ret) {
+ dev_err(&pdev->dev,
+ "failed to parse linux,bootcount-magic, error: %d\n",
+ ret);
+ return ret;
+ }
+
+ bootcount->magic &= ~bootcount->mask;
+
+ return ret;
+}
+
+static int bootcount_nvmem_remove(struct platform_device *pdev)
+{
+ device_remove_file(&pdev->dev, &dev_attr_value);
+
+ return 0;
+}
+
+static const struct of_device_id bootcount_nvmem_match[] = {
+ { .compatible = "linux,bootcount-nvmem" },
+ {},
+};
+
+static struct platform_driver bootcount_nvmem_driver = {
+ .driver = {
+ .name = "bootcount-nvmem",
+ .of_match_table = bootcount_nvmem_match,
+ },
+ .probe = bootcount_nvmem_probe,
+ .remove = bootcount_nvmem_remove,
+};
+
+module_platform_driver(bootcount_nvmem_driver);
+
+MODULE_DEVICE_TABLE(of, bootcount_nvmem_match);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Vaisala Oyj");
+MODULE_DESCRIPTION("Bootcount driver using nvmem compatible registers");
--
2.26.3

2021-04-27 08:29:28

by Nandor Han

[permalink] [raw]
Subject: [PATCH 3/4] nvmem: snvs_lpgpr: use cell stride for regmap size calculation

Using a hard-coded value for calculating the number of registers to read
makes future changes more challenging.

Change the calculation to use the NVMEM cell stride instead of a hard
coded value. This will allow specifying different NVMEM cell sizes.

Signed-off-by: Nandor Han <[email protected]>
---
drivers/nvmem/snvs_lpgpr.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index 4692aa985bd6..35457421314a 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -72,7 +72,7 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
return -EPERM;

return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
- bytes / 4);
+ bytes / priv->cfg.stride);
}

static int snvs_lpgpr_read(void *context, unsigned int offset, void *val,
@@ -81,8 +81,8 @@ static int snvs_lpgpr_read(void *context, unsigned int offset, void *val,
struct snvs_lpgpr_priv *priv = context;
const struct snvs_lpgpr_cfg *dcfg = priv->dcfg;

- return regmap_bulk_read(priv->regmap, dcfg->offset + offset,
- val, bytes / 4);
+ return regmap_bulk_read(priv->regmap, dcfg->offset + offset, val,
+ bytes / priv->cfg.stride);
}

static int snvs_lpgpr_probe(struct platform_device *pdev)
--
2.26.3

2021-04-27 08:30:11

by Nandor Han

[permalink] [raw]
Subject: [PATCH 1/4] dt-bindings: nvmem: Add bootcount-nvmem

Documents the device tree bindings for `bootcount-nvmem` driver.

Signed-off-by: Nandor Han <[email protected]>
---
.../bindings/nvmem/bootcount-nvmem.yaml | 72 +++++++++++++++++++
1 file changed, 72 insertions(+)
create mode 100644 Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml

diff --git a/Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml b/Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml
new file mode 100644
index 000000000000..adbcb2db93a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+# Copyright (c) Vaisala Oyj. All rights reserved.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/nvmem/bootcount-nvmem.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Bootcount NVMEM bindings
+
+maintainers:
+ - Nandor Han <[email protected]>
+
+description: |
+ This binding is intendent to describe the hardware location for
+ storing the bootcount value and magic combo.
+
+ The NVMEM cell size should be 2 or 4 bytes.
+
+properties:
+ compatible:
+ enum:
+ - linux,bootcount-nvmem
+
+ nvmem-cells:
+ description: Phandle to reboot mode nvmem data cell.
+ $ref: /schemas/types.yaml#/definitions/phandle
+
+ nvmem-cell-names:
+ description: Name of the NVMEM cell.
+ $ref: /schemas/types.yaml#/definitions/string
+ enum:
+ - bootcount-regs
+
+ linux,bootcount-magic:
+ description: Override default mask value.
+ $ref: /schemas/types.yaml#/definitions/uint32
+
+required:
+ - compatible
+ - nvmem-cells
+ - nvmem-cell-names
+
+additionalProperties: false
+
+examples:
+ # example with 16 bit nvram cell:
+ - |
+ bootcount {
+ compatible = "linux,bootcount-nvmem";
+ nvmem-cells = <&bootcount_regs>;
+ nvmem-cell-names = "bootcount-regs";
+ };
+
+ rtc@68 {
+ bootcount_regs: bootcount_nvmem_regs@e {
+ reg = <0x0e 0x2>;
+ };
+
+ # example with 32 bit nvram cell:
+ - |
+ bootcount {
+ compatible = "linux,bootcount-nvmem";
+ nvmem-cells = <&bootcount_regs>;
+ nvmem-cell-names = "bootcount-regs";
+ };
+
+ rtc@68 {
+ bootcount_regs: bootcount_nvmem_regs@e {
+ reg = <0x0e 0x4>;
+ };
+
+...
--
2.26.3

2021-04-27 08:32:07

by Nandor Han

[permalink] [raw]
Subject: [PATCH 4/4] nvmem: snvs_lpgpr: support two bytes NVMEM cell size

In some situation is desired to use less than 4 bytes for storing data.
This will allow using the same register for multiple purposes.

Add support for allowing 2 bytes granularity for NVMEM cells.

Signed-off-by: Nandor Han <[email protected]>
---
drivers/nvmem/snvs_lpgpr.c | 67 ++++++++++++++++++++++++++++++++++----
1 file changed, 61 insertions(+), 6 deletions(-)

diff --git a/drivers/nvmem/snvs_lpgpr.c b/drivers/nvmem/snvs_lpgpr.c
index 35457421314a..44614f3d68f0 100644
--- a/drivers/nvmem/snvs_lpgpr.c
+++ b/drivers/nvmem/snvs_lpgpr.c
@@ -21,6 +21,9 @@
#define IMX_GPR_SL BIT(5)
#define IMX_GPR_HL BIT(5)

+#define REGMAP_FIELD_SIZE 16
+#define REGMAP_FIELDS_PER_REG 2
+
struct snvs_lpgpr_cfg {
int offset;
int offset_hplr;
@@ -33,6 +36,7 @@ struct snvs_lpgpr_priv {
struct regmap *regmap;
struct nvmem_config cfg;
const struct snvs_lpgpr_cfg *dcfg;
+ struct regmap_field **reg_fields;
};

static const struct snvs_lpgpr_cfg snvs_lpgpr_cfg_imx6q = {
@@ -56,6 +60,11 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
const struct snvs_lpgpr_cfg *dcfg = priv->dcfg;
unsigned int lock_reg;
int ret;
+ u32 regval;
+ unsigned int field_id;
+
+ if (offset + bytes > dcfg->size)
+ return -EINVAL;

ret = regmap_read(priv->regmap, dcfg->offset_hplr, &lock_reg);
if (ret < 0)
@@ -71,8 +80,16 @@ static int snvs_lpgpr_write(void *context, unsigned int offset, void *val,
if (lock_reg & IMX_GPR_HL)
return -EPERM;

- return regmap_bulk_write(priv->regmap, dcfg->offset + offset, val,
- bytes / priv->cfg.stride);
+ if (bytes == (REGMAP_FIELD_SIZE >> 3)) {
+ regval = *(u16 *)(val);
+ field_id = offset / REGMAP_FIELDS_PER_REG;
+ ret = regmap_field_write(priv->reg_fields[field_id], regval);
+ } else {
+ ret = regmap_bulk_write(priv->regmap, dcfg->offset + offset,
+ val, bytes / priv->cfg.stride);
+ }
+
+ return ret;
}

static int snvs_lpgpr_read(void *context, unsigned int offset, void *val,
@@ -80,9 +97,27 @@ static int snvs_lpgpr_read(void *context, unsigned int offset, void *val,
{
struct snvs_lpgpr_priv *priv = context;
const struct snvs_lpgpr_cfg *dcfg = priv->dcfg;
+ int ret;
+ u32 regval;
+ unsigned int field_id;

- return regmap_bulk_read(priv->regmap, dcfg->offset + offset, val,
- bytes / priv->cfg.stride);
+ if (offset + bytes > dcfg->size)
+ return -EINVAL;
+
+ if (bytes == (REGMAP_FIELD_SIZE >> 3)) {
+ field_id = offset / REGMAP_FIELDS_PER_REG;
+ ret = regmap_field_read(priv->reg_fields[field_id], &regval);
+ if (ret)
+ return ret;
+
+ *(u16 *)(val) = regval;
+ } else {
+ ret = regmap_bulk_read(priv->regmap, dcfg->offset + offset, val,
+ bytes / priv->cfg.stride);
+ if (ret)
+ return ret;
+ }
+ return 0;
}

static int snvs_lpgpr_probe(struct platform_device *pdev)
@@ -94,6 +129,8 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
struct nvmem_config *cfg;
struct nvmem_device *nvmem;
const struct snvs_lpgpr_cfg *dcfg;
+ int i;
+ int fields_count;

if (!node)
return -ENOENT;
@@ -121,13 +158,31 @@ static int snvs_lpgpr_probe(struct platform_device *pdev)
cfg->priv = priv;
cfg->name = dev_name(dev);
cfg->dev = dev;
- cfg->stride = 4;
- cfg->word_size = 4;
+ cfg->stride = 2;
+ cfg->word_size = 2;
cfg->size = dcfg->size;
cfg->owner = THIS_MODULE;
cfg->reg_read = snvs_lpgpr_read;
cfg->reg_write = snvs_lpgpr_write;

+ fields_count = priv->dcfg->size / priv->cfg.stride;
+ priv->reg_fields = devm_kzalloc(
+ dev, sizeof(struct regmap_field *) * fields_count, GFP_KERNEL);
+ if (!priv->reg_fields)
+ return -ENOMEM;
+
+ for (i = 0; i < fields_count; i++) {
+ size_t field_start = i * REGMAP_FIELD_SIZE;
+ size_t field_end = field_start + REGMAP_FIELD_SIZE - 1;
+ const struct reg_field field =
+ REG_FIELD(dcfg->offset, field_start, field_end);
+
+ priv->reg_fields[i] =
+ devm_regmap_field_alloc(dev, priv->regmap, field);
+ if (IS_ERR(priv->reg_fields[i]))
+ return PTR_ERR(priv->reg_fields[i]);
+ }
+
nvmem = devm_nvmem_register(dev, cfg);

return PTR_ERR_OR_ZERO(nvmem);
--
2.26.3

2021-04-27 12:58:00

by Rob Herring (Arm)

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: nvmem: Add bootcount-nvmem

On Tue, 27 Apr 2021 11:26:31 +0300, Nandor Han wrote:
> Documents the device tree bindings for `bootcount-nvmem` driver.
>
> Signed-off-by: Nandor Han <[email protected]>
> ---
> .../bindings/nvmem/bootcount-nvmem.yaml | 72 +++++++++++++++++++
> 1 file changed, 72 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml
>

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Error: Documentation/devicetree/bindings/nvmem/bootcount-nvmem.example.dts:34.1-2 syntax error
FATAL ERROR: Unable to parse input tree
make[1]: *** [scripts/Makefile.lib:377: Documentation/devicetree/bindings/nvmem/bootcount-nvmem.example.dt.yaml] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [Makefile:1414: dt_binding_check] Error 2

See https://patchwork.ozlabs.org/patch/1470591

This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.

2021-04-27 13:09:15

by Nandor Han

[permalink] [raw]
Subject: Re: [PATCH 1/4] dt-bindings: nvmem: Add bootcount-nvmem

> On Tue, 27 Apr 2021 11:26:31 +0300, Nandor Han wrote:
>> Documents the device tree bindings for `bootcount-nvmem` driver.
>>
>> Signed-off-by: Nandor Han <[email protected]>
>> ---
>> .../bindings/nvmem/bootcount-nvmem.yaml | 72 +++++++++++++++++++
>> 1 file changed, 72 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/nvmem/bootcount-nvmem.yaml
>>
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> Error: Documentation/devicetree/bindings/nvmem/bootcount-nvmem.example.dts:34.1-2 syntax error
> FATAL ERROR: Unable to parse input tree
> make[1]: *** [scripts/Makefile.lib:377: Documentation/devicetree/bindings/nvmem/bootcount-nvmem.example.dt.yaml] Error 1
> make[1]: *** Waiting for unfinished jobs....
> make: *** [Makefile:1414: dt_binding_check] Error 2
>
> See https://patchwork.ozlabs.org/patch/1470591
>
> This check can fail if there are any dependencies. The base for a patch
> series is generally the most recent rc1.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit.
>

Thanks for the quick feedback Rob.

I did run some checks, maybe not well enough.
I will have a look to your suggestions.

Regards,
Nandor