]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
sysreset: syscon: Support value property
authorBin Meng <bin.meng@windriver.com>
Tue, 23 Jun 2020 05:29:43 +0000 (22:29 -0700)
committerAndes <uboot@andestech.com>
Fri, 24 Jul 2020 06:55:49 +0000 (14:55 +0800)
Per the DT binding, <mask> and <value> property can have either one
or both, and if <value> is missing, <mask> should be used, which is
what current U-Boot sysreset_syscon driver supports.

This adds support to the <value> property to the driver, and <mask>
semantics is updated to really be a mask to the value if both exist.

Signed-off-by: Bin Meng <bin.meng@windriver.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Pragnesh Patel <pragnesh.patel@sifive.com>
drivers/sysreset/sysreset_syscon.c

index caf24823cc192f8fe533c15497702375553a3c26..1c47486614546b41e16060d800090e77fb13482f 100644 (file)
@@ -19,6 +19,7 @@ struct syscon_reboot_priv {
        struct regmap *regmap;
        unsigned int offset;
        unsigned int mask;
+       unsigned int value;
 };
 
 static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
@@ -29,7 +30,7 @@ static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
        if (type != driver_data)
                return -EPROTONOSUPPORT;
 
-       regmap_write(priv->regmap, priv->offset, priv->mask);
+       regmap_update_bits(priv->regmap, priv->offset, priv->mask, priv->value);
 
        return -EINPROGRESS;
 }
@@ -42,6 +43,7 @@ int syscon_reboot_probe(struct udevice *dev)
 {
        struct syscon_reboot_priv *priv = dev_get_priv(dev);
        int err;
+       int mask_err, value_err;
 
        priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap");
        if (IS_ERR(priv->regmap)) {
@@ -55,10 +57,20 @@ int syscon_reboot_probe(struct udevice *dev)
                return -ENOENT;
        }
 
-       err = dev_read_u32(dev, "mask", &priv->mask);
-       if (err) {
-               pr_err("unable to find mask\n");
-               return -ENOENT;
+       mask_err = dev_read_u32(dev, "mask", &priv->mask);
+       value_err = dev_read_u32(dev, "value", &priv->value);
+       if (mask_err && value_err) {
+               pr_err("unable to find mask and value\n");
+               return -EINVAL;
+       }
+
+       if (value_err) {
+               /* support old binding */
+               priv->value = priv->mask;
+               priv->mask = 0xffffffff;
+       } else if (mask_err) {
+               /* support value without mask*/
+               priv->mask = 0xffffffff;
        }
 
        return 0;