Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

power: reset: Add msm restart support

Add support for restart and poweroff functionality present on MSM chipsets
with the MPM2 ps-hold hardware.

Signed-off-by: Abhimanyu Kapur <abhimany@codeaurora.org>
Tested-by: Ivan T. Ivanov <iivanov@mm-sol.com>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Anton Vorontsov <anton@enomsg.org>

authored by

Abhimanyu Kapur and committed by
Anton Vorontsov
78be3176 68ace3e1

+97
+17
Documentation/devicetree/bindings/power_supply/msm-poweroff.txt
··· 1 + MSM Restart Driver 2 + 3 + A power supply hold (ps-hold) bit is set to power the msm chipsets. 4 + Clearing that bit allows us to restart/poweroff. The difference 5 + between poweroff and restart is determined by unique power manager IC 6 + settings. 7 + 8 + Required Properties: 9 + -compatible: "qcom,pshold" 10 + -reg: Specifies the physical address of the ps-hold register 11 + 12 + Example: 13 + 14 + restart@fc4ab000 { 15 + compatible = "qcom,pshold"; 16 + reg = <0xfc4ab000 0x4>; 17 + };
+6
drivers/power/reset/Kconfig
··· 14 14 If your board needs a GPIO high/low to power down, say Y and 15 15 create a binding in your devicetree. 16 16 17 + config POWER_RESET_MSM 18 + bool "Qualcomm MSM power-off driver" 19 + depends on POWER_RESET && ARCH_MSM 20 + help 21 + Power off and restart support for Qualcomm boards. 22 + 17 23 config POWER_RESET_QNAP 18 24 bool "QNAP power-off driver" 19 25 depends on OF_GPIO && POWER_RESET && PLAT_ORION
+1
drivers/power/reset/Makefile
··· 1 1 obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o 2 + obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o 2 3 obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o 3 4 obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o 4 5 obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
+73
drivers/power/reset/msm-poweroff.c
··· 1 + /* Copyright (c) 2013, The Linux Foundation. All rights reserved. 2 + * 3 + * This program is free software; you can redistribute it and/or modify 4 + * it under the terms of the GNU General Public License version 2 and 5 + * only version 2 as published by the Free Software Foundation. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + * 12 + */ 13 + 14 + #include <linux/delay.h> 15 + #include <linux/err.h> 16 + #include <linux/init.h> 17 + #include <linux/kernel.h> 18 + #include <linux/io.h> 19 + #include <linux/of.h> 20 + #include <linux/platform_device.h> 21 + #include <linux/module.h> 22 + #include <linux/reboot.h> 23 + 24 + #include <asm/system_misc.h> 25 + 26 + static void __iomem *msm_ps_hold; 27 + 28 + static void do_msm_restart(enum reboot_mode reboot_mode, const char *cmd) 29 + { 30 + writel(0, msm_ps_hold); 31 + mdelay(10000); 32 + } 33 + 34 + static void do_msm_poweroff(void) 35 + { 36 + /* TODO: Add poweroff capability */ 37 + do_msm_restart(REBOOT_HARD, NULL); 38 + } 39 + 40 + static int msm_restart_probe(struct platform_device *pdev) 41 + { 42 + struct device *dev = &pdev->dev; 43 + struct resource *mem; 44 + 45 + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 46 + msm_ps_hold = devm_ioremap_resource(dev, mem); 47 + if (IS_ERR(msm_ps_hold)) 48 + return PTR_ERR(msm_ps_hold); 49 + 50 + pm_power_off = do_msm_poweroff; 51 + arm_pm_restart = do_msm_restart; 52 + return 0; 53 + } 54 + 55 + static const struct of_device_id of_msm_restart_match[] = { 56 + { .compatible = "qcom,pshold", }, 57 + {}, 58 + }; 59 + MODULE_DEVICE_TABLE(of, of_msm_restart_match); 60 + 61 + static struct platform_driver msm_restart_driver = { 62 + .probe = msm_restart_probe, 63 + .driver = { 64 + .name = "msm-restart", 65 + .of_match_table = of_match_ptr(of_msm_restart_match), 66 + }, 67 + }; 68 + 69 + static int __init msm_restart_init(void) 70 + { 71 + return platform_driver_register(&msm_restart_driver); 72 + } 73 + device_initcall(msm_restart_init);