Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  Copyright (C) 2021, Qing Zhang <zhangqing@loongson.cn>
0004  *  Loongson-2K1000 reset support
0005  */
0006 
0007 #include <linux/of_address.h>
0008 #include <linux/pm.h>
0009 #include <asm/reboot.h>
0010 
0011 #define PM1_STS     0x0c /* Power Management 1 Status Register */
0012 #define PM1_CNT     0x14 /* Power Management 1 Control Register */
0013 #define RST_CNT     0x30 /* Reset Control Register */
0014 
0015 static void __iomem *base;
0016 
0017 static void ls2k_restart(char *command)
0018 {
0019     writel(0x1, base + RST_CNT);
0020 }
0021 
0022 static void ls2k_poweroff(void)
0023 {
0024     /* Clear */
0025     writel((readl(base + PM1_STS) & 0xffffffff), base + PM1_STS);
0026     /* Sleep Enable | Soft Off*/
0027     writel(GENMASK(12, 10) | BIT(13), base + PM1_CNT);
0028 }
0029 
0030 static int ls2k_reset_init(void)
0031 {
0032     struct device_node *np;
0033 
0034     np = of_find_compatible_node(NULL, NULL, "loongson,ls2k-pm");
0035     if (!np) {
0036         pr_info("Failed to get PM node\n");
0037         return -ENODEV;
0038     }
0039 
0040     base = of_iomap(np, 0);
0041     of_node_put(np);
0042     if (!base) {
0043         pr_info("Failed to map PM register base address\n");
0044         return -ENOMEM;
0045     }
0046 
0047     _machine_restart = ls2k_restart;
0048     pm_power_off = ls2k_poweroff;
0049 
0050     return 0;
0051 }
0052 
0053 arch_initcall(ls2k_reset_init);