197fb5e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
278be3176SAbhimanyu Kapur /* Copyright (c) 2013, The Linux Foundation. All rights reserved.
378be3176SAbhimanyu Kapur */
478be3176SAbhimanyu Kapur
578be3176SAbhimanyu Kapur #include <linux/delay.h>
678be3176SAbhimanyu Kapur #include <linux/err.h>
778be3176SAbhimanyu Kapur #include <linux/init.h>
878be3176SAbhimanyu Kapur #include <linux/kernel.h>
978be3176SAbhimanyu Kapur #include <linux/io.h>
1078be3176SAbhimanyu Kapur #include <linux/of.h>
1178be3176SAbhimanyu Kapur #include <linux/platform_device.h>
1278be3176SAbhimanyu Kapur #include <linux/module.h>
1378be3176SAbhimanyu Kapur #include <linux/reboot.h>
1418a702e0SPramod Gurav #include <linux/pm.h>
1578be3176SAbhimanyu Kapur
1678be3176SAbhimanyu Kapur static void __iomem *msm_ps_hold;
deassert_pshold(struct notifier_block * nb,unsigned long action,void * data)17fd8b8f17SBjorn Andersson static int deassert_pshold(struct notifier_block *nb, unsigned long action,
1818a702e0SPramod Gurav void *data)
1978be3176SAbhimanyu Kapur {
2078be3176SAbhimanyu Kapur writel(0, msm_ps_hold);
2178be3176SAbhimanyu Kapur mdelay(10000);
2218a702e0SPramod Gurav
2318a702e0SPramod Gurav return NOTIFY_DONE;
2478be3176SAbhimanyu Kapur }
2578be3176SAbhimanyu Kapur
2618a702e0SPramod Gurav static struct notifier_block restart_nb = {
27fd8b8f17SBjorn Andersson .notifier_call = deassert_pshold,
2818a702e0SPramod Gurav .priority = 128,
2918a702e0SPramod Gurav };
3018a702e0SPramod Gurav
do_msm_poweroff(void)3178be3176SAbhimanyu Kapur static void do_msm_poweroff(void)
3278be3176SAbhimanyu Kapur {
33fd8b8f17SBjorn Andersson deassert_pshold(&restart_nb, 0, NULL);
3478be3176SAbhimanyu Kapur }
3578be3176SAbhimanyu Kapur
msm_restart_probe(struct platform_device * pdev)3678be3176SAbhimanyu Kapur static int msm_restart_probe(struct platform_device *pdev)
3778be3176SAbhimanyu Kapur {
38*19223ffaSYangtao Li msm_ps_hold = devm_platform_ioremap_resource(pdev, 0);
3978be3176SAbhimanyu Kapur if (IS_ERR(msm_ps_hold))
4078be3176SAbhimanyu Kapur return PTR_ERR(msm_ps_hold);
4178be3176SAbhimanyu Kapur
4218a702e0SPramod Gurav register_restart_handler(&restart_nb);
4318a702e0SPramod Gurav
4478be3176SAbhimanyu Kapur pm_power_off = do_msm_poweroff;
4518a702e0SPramod Gurav
4678be3176SAbhimanyu Kapur return 0;
4778be3176SAbhimanyu Kapur }
4878be3176SAbhimanyu Kapur
4978be3176SAbhimanyu Kapur static const struct of_device_id of_msm_restart_match[] = {
5078be3176SAbhimanyu Kapur { .compatible = "qcom,pshold", },
5178be3176SAbhimanyu Kapur {},
5278be3176SAbhimanyu Kapur };
5378be3176SAbhimanyu Kapur MODULE_DEVICE_TABLE(of, of_msm_restart_match);
5478be3176SAbhimanyu Kapur
5578be3176SAbhimanyu Kapur static struct platform_driver msm_restart_driver = {
5678be3176SAbhimanyu Kapur .probe = msm_restart_probe,
5778be3176SAbhimanyu Kapur .driver = {
5878be3176SAbhimanyu Kapur .name = "msm-restart",
5978be3176SAbhimanyu Kapur .of_match_table = of_match_ptr(of_msm_restart_match),
6078be3176SAbhimanyu Kapur },
6178be3176SAbhimanyu Kapur };
6278be3176SAbhimanyu Kapur
msm_restart_init(void)6378be3176SAbhimanyu Kapur static int __init msm_restart_init(void)
6478be3176SAbhimanyu Kapur {
6578be3176SAbhimanyu Kapur return platform_driver_register(&msm_restart_driver);
6678be3176SAbhimanyu Kapur }
6778be3176SAbhimanyu Kapur device_initcall(msm_restart_init);
68