treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157
[sfrench/cifs-2.6.git] / drivers / power / reset / syscon-reboot.c
index 7d0d269a0837c0b84e9f72eeabbab354159a3b8e..62fbba0df9710de0dc4763509e35e899e5e6778f 100644 (file)
@@ -1,18 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Generic Syscon Reboot Driver
  *
  * Copyright (c) 2013, Applied Micro Circuits Corporation
  * Author: Feng Kan <fkan@apm.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 #include <linux/delay.h>
 #include <linux/io.h>
@@ -27,6 +18,7 @@
 struct syscon_reboot_context {
        struct regmap *map;
        u32 offset;
+       u32 value;
        u32 mask;
        struct notifier_block restart_handler;
 };
@@ -39,7 +31,7 @@ static int syscon_restart_handle(struct notifier_block *this,
                                        restart_handler);
 
        /* Issue the reboot */
-       regmap_write(ctx->map, ctx->offset, ctx->mask);
+       regmap_update_bits(ctx->map, ctx->offset, ctx->mask, ctx->value);
 
        mdelay(1000);
 
@@ -51,6 +43,7 @@ static int syscon_reboot_probe(struct platform_device *pdev)
 {
        struct syscon_reboot_context *ctx;
        struct device *dev = &pdev->dev;
+       int mask_err, value_err;
        int err;
 
        ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
@@ -64,8 +57,21 @@ static int syscon_reboot_probe(struct platform_device *pdev)
        if (of_property_read_u32(pdev->dev.of_node, "offset", &ctx->offset))
                return -EINVAL;
 
-       if (of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask))
+       value_err = of_property_read_u32(pdev->dev.of_node, "value", &ctx->value);
+       mask_err = of_property_read_u32(pdev->dev.of_node, "mask", &ctx->mask);
+       if (value_err && mask_err) {
+               dev_err(dev, "unable to read 'value' and 'mask'");
                return -EINVAL;
+       }
+
+       if (value_err) {
+               /* support old binding */
+               ctx->value = ctx->mask;
+               ctx->mask = 0xFFFFFFFF;
+       } else if (mask_err) {
+               /* support value without mask*/
+               ctx->mask = 0xFFFFFFFF;
+       }
 
        ctx->restart_handler.notifier_call = syscon_restart_handle;
        ctx->restart_handler.priority = 192;