0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/delay.h>
0014 #include <linux/io.h>
0015 #include <linux/notifier.h>
0016 #include <linux/of_device.h>
0017 #include <linux/of_address.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/reboot.h>
0020 #include <linux/stat.h>
0021 #include <linux/slab.h>
0022
0023 struct xgene_reboot_context {
0024 struct device *dev;
0025 void *csr;
0026 u32 mask;
0027 struct notifier_block restart_handler;
0028 };
0029
0030 static int xgene_restart_handler(struct notifier_block *this,
0031 unsigned long mode, void *cmd)
0032 {
0033 struct xgene_reboot_context *ctx =
0034 container_of(this, struct xgene_reboot_context,
0035 restart_handler);
0036
0037
0038 writel(ctx->mask, ctx->csr);
0039
0040 mdelay(1000);
0041
0042 dev_emerg(ctx->dev, "Unable to restart system\n");
0043
0044 return NOTIFY_DONE;
0045 }
0046
0047 static int xgene_reboot_probe(struct platform_device *pdev)
0048 {
0049 struct xgene_reboot_context *ctx;
0050 struct device *dev = &pdev->dev;
0051 int err;
0052
0053 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
0054 if (!ctx)
0055 return -ENOMEM;
0056
0057 ctx->csr = of_iomap(dev->of_node, 0);
0058 if (!ctx->csr) {
0059 dev_err(dev, "can not map resource\n");
0060 return -ENODEV;
0061 }
0062
0063 if (of_property_read_u32(dev->of_node, "mask", &ctx->mask))
0064 ctx->mask = 0xFFFFFFFF;
0065
0066 ctx->dev = dev;
0067 ctx->restart_handler.notifier_call = xgene_restart_handler;
0068 ctx->restart_handler.priority = 128;
0069 err = register_restart_handler(&ctx->restart_handler);
0070 if (err) {
0071 iounmap(ctx->csr);
0072 dev_err(dev, "cannot register restart handler (err=%d)\n", err);
0073 }
0074
0075 return err;
0076 }
0077
0078 static const struct of_device_id xgene_reboot_of_match[] = {
0079 { .compatible = "apm,xgene-reboot" },
0080 {}
0081 };
0082
0083 static struct platform_driver xgene_reboot_driver = {
0084 .probe = xgene_reboot_probe,
0085 .driver = {
0086 .name = "xgene-reboot",
0087 .of_match_table = xgene_reboot_of_match,
0088 },
0089 };
0090
0091 static int __init xgene_reboot_init(void)
0092 {
0093 return platform_driver_register(&xgene_reboot_driver);
0094 }
0095 device_initcall(xgene_reboot_init);