1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * AppliedMicro X-Gene SoC Reboot Driver 4 * 5 * Copyright (c) 2013, Applied Micro Circuits Corporation 6 * Author: Feng Kan <fkan@apm.com> 7 * Author: Loc Ho <lho@apm.com> 8 * 9 * This driver provides system reboot functionality for APM X-Gene SoC. 10 * For system shutdown, this is board specify. If a board designer 11 * implements GPIO shutdown, use the gpio-poweroff.c driver. 12 */ 13 #include <linux/delay.h> 14 #include <linux/io.h> 15 #include <linux/notifier.h> 16 #include <linux/of.h> 17 #include <linux/of_address.h> 18 #include <linux/platform_device.h> 19 #include <linux/reboot.h> 20 #include <linux/stat.h> 21 #include <linux/slab.h> 22 23 struct xgene_reboot_context { 24 struct device *dev; 25 void __iomem *csr; 26 u32 mask; 27 }; 28 29 static int xgene_restart_handler(struct sys_off_data *data) 30 { 31 struct xgene_reboot_context *ctx = data->cb_data; 32 33 /* Issue the reboot */ 34 writel(ctx->mask, ctx->csr); 35 36 mdelay(1000); 37 38 dev_emerg(ctx->dev, "Unable to restart system\n"); 39 40 return NOTIFY_DONE; 41 } 42 43 static int xgene_reboot_probe(struct platform_device *pdev) 44 { 45 struct xgene_reboot_context *ctx; 46 struct device *dev = &pdev->dev; 47 int err; 48 49 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); 50 if (!ctx) 51 return -ENOMEM; 52 53 ctx->csr = devm_platform_ioremap_resource(pdev, 0); 54 if (IS_ERR(ctx->csr)) { 55 dev_err(dev, "can not map resource\n"); 56 return PTR_ERR(ctx->csr); 57 } 58 59 if (of_property_read_u32(dev->of_node, "mask", &ctx->mask)) 60 ctx->mask = 0xFFFFFFFF; 61 62 ctx->dev = dev; 63 err = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART, 128, 64 xgene_restart_handler, ctx); 65 if (err) 66 dev_err(dev, "cannot register restart handler (err=%d)\n", err); 67 68 return err; 69 } 70 71 static const struct of_device_id xgene_reboot_of_match[] = { 72 { .compatible = "apm,xgene-reboot" }, 73 {} 74 }; 75 76 static struct platform_driver xgene_reboot_driver = { 77 .probe = xgene_reboot_probe, 78 .driver = { 79 .name = "xgene-reboot", 80 .of_match_table = xgene_reboot_of_match, 81 }, 82 }; 83 builtin_platform_driver(xgene_reboot_driver); 84