summaryrefslogtreecommitdiff
path: root/drivers/platform/mips/ls2k-reset.c
diff options
context:
space:
mode:
authorQing Zhang <zhangqing@loongson.cn>2021-11-26 04:52:14 +0300
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>2022-01-02 16:13:09 +0300
commit7eb7819a2e12461a43eb701e401460ed424a425d (patch)
tree4978576428b6adc3cb445c4a9b178167ed2264bd /drivers/platform/mips/ls2k-reset.c
parentfc5bb239d5b3500d034559e0c5ecb67bbae69de7 (diff)
downloadlinux-7eb7819a2e12461a43eb701e401460ed424a425d.tar.xz
MIPS: Loongson64: Add Loongson-2K1000 reset platform driver
Add power management register operations to support reboot and poweroff. Signed-off-by: Qing Zhang <zhangqing@loongson.cn> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Diffstat (limited to 'drivers/platform/mips/ls2k-reset.c')
-rw-r--r--drivers/platform/mips/ls2k-reset.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/platform/mips/ls2k-reset.c b/drivers/platform/mips/ls2k-reset.c
new file mode 100644
index 000000000000..b70e7b8a092c
--- /dev/null
+++ b/drivers/platform/mips/ls2k-reset.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2021, Qing Zhang <zhangqing@loongson.cn>
+ * Loongson-2K1000 reset support
+ */
+
+#include <linux/of_address.h>
+#include <linux/pm.h>
+#include <asm/reboot.h>
+
+#define PM1_STS 0x0c /* Power Management 1 Status Register */
+#define PM1_CNT 0x14 /* Power Management 1 Control Register */
+#define RST_CNT 0x30 /* Reset Control Register */
+
+static void __iomem *base;
+
+static void ls2k_restart(char *command)
+{
+ writel(0x1, base + RST_CNT);
+}
+
+static void ls2k_poweroff(void)
+{
+ /* Clear */
+ writel((readl(base + PM1_STS) & 0xffffffff), base + PM1_STS);
+ /* Sleep Enable | Soft Off*/
+ writel(GENMASK(12, 10) | BIT(13), base + PM1_CNT);
+}
+
+static int ls2k_reset_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_compatible_node(NULL, NULL, "loongson,ls2k-pm");
+ if (!np) {
+ pr_info("Failed to get PM node\n");
+ return -ENODEV;
+ }
+
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_info("Failed to map PM register base address\n");
+ return -ENOMEM;
+ }
+
+ _machine_restart = ls2k_restart;
+ pm_power_off = ls2k_poweroff;
+
+ of_node_put(np);
+ return 0;
+}
+
+arch_initcall(ls2k_reset_init);