1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (C) 2016 Broadcom 3 4 #include <linux/io.h> 5 #include <linux/mod_devicetable.h> 6 #include <linux/platform_device.h> 7 #include <linux/reboot.h> 8 9 #define RSTMGR_REG_WR_ACCESS_OFFSET 0 10 #define RSTMGR_REG_CHIP_SOFT_RST_OFFSET 4 11 12 #define RSTMGR_WR_PASSWORD 0xa5a5 13 #define RSTMGR_WR_PASSWORD_SHIFT 8 14 #define RSTMGR_WR_ACCESS_ENABLE 1 15 16 static void __iomem *kona_reset_base; 17 18 static int kona_reset_handler(struct sys_off_data *data) 19 { 20 /* 21 * A soft reset is triggered by writing a 0 to bit 0 of the soft reset 22 * register. To write to that register we must first write the password 23 * and the enable bit in the write access enable register. 24 */ 25 writel((RSTMGR_WR_PASSWORD << RSTMGR_WR_PASSWORD_SHIFT) | 26 RSTMGR_WR_ACCESS_ENABLE, 27 kona_reset_base + RSTMGR_REG_WR_ACCESS_OFFSET); 28 writel(0, kona_reset_base + RSTMGR_REG_CHIP_SOFT_RST_OFFSET); 29 30 return NOTIFY_DONE; 31 } 32 33 static int kona_reset_probe(struct platform_device *pdev) 34 { 35 kona_reset_base = devm_platform_ioremap_resource(pdev, 0); 36 if (IS_ERR(kona_reset_base)) 37 return PTR_ERR(kona_reset_base); 38 39 return devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 40 128, kona_reset_handler, NULL); 41 } 42 43 static const struct of_device_id of_match[] = { 44 { .compatible = "brcm,bcm21664-resetmgr" }, 45 {}, 46 }; 47 48 static struct platform_driver bcm_kona_reset_driver = { 49 .probe = kona_reset_probe, 50 .driver = { 51 .name = "brcm-kona-reset", 52 .of_match_table = of_match, 53 }, 54 }; 55 56 builtin_platform_driver(bcm_kona_reset_driver); 57