summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Meng <bin.meng@windriver.com>2020-06-22 22:29:43 -0700
committerAndes <uboot@andestech.com>2020-07-24 14:55:49 +0800
commit9cdfade85ebeab73ce001e3dfdb8c529bf3cabed (patch)
treef76e3dbcc44e87583911c24f1a45cb051a8a7932
parent1ce8182b0f7254d0d01e309341c35bbc1b8c10e4 (diff)
downloadu-boot-9cdfade85ebeab73ce001e3dfdb8c529bf3cabed.tar.gz
u-boot-9cdfade85ebeab73ce001e3dfdb8c529bf3cabed.tar.bz2
u-boot-9cdfade85ebeab73ce001e3dfdb8c529bf3cabed.zip
sysreset: syscon: Support value property
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>
-rw-r--r--drivers/sysreset/sysreset_syscon.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/drivers/sysreset/sysreset_syscon.c b/drivers/sysreset/sysreset_syscon.c
index caf24823cc..1c47486614 100644
--- a/drivers/sysreset/sysreset_syscon.c
+++ b/drivers/sysreset/sysreset_syscon.c
@@ -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;