diff options
Diffstat (limited to 'drivers/pinctrl/qcom/pinctrl-msm.c')
-rw-r--r-- | drivers/pinctrl/qcom/pinctrl-msm.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 9175bbc298c7..80a64cad907d 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -12,6 +12,7 @@ | |||
12 | * GNU General Public License for more details. | 12 | * GNU General Public License for more details. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
16 | #include <linux/io.h> | 17 | #include <linux/io.h> |
17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
@@ -27,12 +28,15 @@ | |||
27 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
28 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
29 | 30 | ||
31 | #include <asm/system_misc.h> | ||
32 | |||
30 | #include "../core.h" | 33 | #include "../core.h" |
31 | #include "../pinconf.h" | 34 | #include "../pinconf.h" |
32 | #include "pinctrl-msm.h" | 35 | #include "pinctrl-msm.h" |
33 | #include "../pinctrl-utils.h" | 36 | #include "../pinctrl-utils.h" |
34 | 37 | ||
35 | #define MAX_NR_GPIO 300 | 38 | #define MAX_NR_GPIO 300 |
39 | #define PS_HOLD_OFFSET 0x820 | ||
36 | 40 | ||
37 | /** | 41 | /** |
38 | * struct msm_pinctrl - state for a pinctrl-msm device | 42 | * struct msm_pinctrl - state for a pinctrl-msm device |
@@ -850,6 +854,30 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) | |||
850 | return 0; | 854 | return 0; |
851 | } | 855 | } |
852 | 856 | ||
857 | #ifdef CONFIG_ARM | ||
858 | static void __iomem *msm_ps_hold; | ||
859 | |||
860 | static void msm_reset(enum reboot_mode reboot_mode, const char *cmd) | ||
861 | { | ||
862 | writel(0, msm_ps_hold); | ||
863 | mdelay(10000); | ||
864 | } | ||
865 | |||
866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) | ||
867 | { | ||
868 | int i = 0; | ||
869 | const struct msm_function *func = pctrl->soc->functions; | ||
870 | |||
871 | for (; i <= pctrl->soc->nfunctions; i++) | ||
872 | if (!strcmp(func[i].name, "ps_hold")) { | ||
873 | msm_ps_hold = pctrl->regs + PS_HOLD_OFFSET; | ||
874 | arm_pm_restart = msm_reset; | ||
875 | } | ||
876 | } | ||
877 | #else | ||
878 | static void msm_pinctrl_setup_pm_reset(const struct msm_pinctrl *pctrl) {} | ||
879 | #endif | ||
880 | |||
853 | int msm_pinctrl_probe(struct platform_device *pdev, | 881 | int msm_pinctrl_probe(struct platform_device *pdev, |
854 | const struct msm_pinctrl_soc_data *soc_data) | 882 | const struct msm_pinctrl_soc_data *soc_data) |
855 | { | 883 | { |
@@ -873,6 +901,8 @@ int msm_pinctrl_probe(struct platform_device *pdev, | |||
873 | if (IS_ERR(pctrl->regs)) | 901 | if (IS_ERR(pctrl->regs)) |
874 | return PTR_ERR(pctrl->regs); | 902 | return PTR_ERR(pctrl->regs); |
875 | 903 | ||
904 | msm_pinctrl_setup_pm_reset(pctrl); | ||
905 | |||
876 | pctrl->irq = platform_get_irq(pdev, 0); | 906 | pctrl->irq = platform_get_irq(pdev, 0); |
877 | if (pctrl->irq < 0) { | 907 | if (pctrl->irq < 0) { |
878 | dev_err(&pdev->dev, "No interrupt defined for msmgpio\n"); | 908 | dev_err(&pdev->dev, "No interrupt defined for msmgpio\n"); |