diff options
author | Josh Cartwright <joshc@codeaurora.org> | 2014-09-23 16:59:53 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2014-09-26 04:36:30 -0400 |
commit | cf1fc187628913070c3e418ce0e205732435aa2f (patch) | |
tree | 6118538b49be97a330baf576592e01435e1835e7 /drivers/pinctrl/qcom | |
parent | 0a332c96c29c84cd9205c29dfa1add4667456059 (diff) |
pinctrl: qcom: use restart_notifier mechanism for ps_hold
By converting to the restart_notifier mechanism for restart, we allow
for other mechanisms, like the watchdog, to be used for restart in the
case where PS_HOLD has failed to reset the chip.
Since this mechanism may be one of several mechanisms registered, change
the post-ps_hold write timeout to be a more reasonable 1 second instead
of 10 seconds.
Choose priority 128, as according to documentation, this mechanism "is
sufficient to restart the entire system".
Tested-by: Pramod Gurav <pramod.gurav@smartplayin.com>
Signed-off-by: Josh Cartwright <joshc@codeaurora.org>
Acked-by: Bjorn Andersson <bjorn.andersson@sonymobile.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/qcom')
-rw-r--r-- | drivers/pinctrl/qcom/pinctrl-msm.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index d5ed1272b928..d30dddd21323 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c | |||
@@ -27,8 +27,7 @@ | |||
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
30 | 30 | #include <linux/reboot.h> | |
31 | #include <asm/system_misc.h> | ||
32 | 31 | ||
33 | #include "../core.h" | 32 | #include "../core.h" |
34 | #include "../pinconf.h" | 33 | #include "../pinconf.h" |
@@ -43,6 +42,7 @@ | |||
43 | * @dev: device handle. | 42 | * @dev: device handle. |
44 | * @pctrl: pinctrl handle. | 43 | * @pctrl: pinctrl handle. |
45 | * @chip: gpiochip handle. | 44 | * @chip: gpiochip handle. |
45 | * @restart_nb: restart notifier block. | ||
46 | * @irq: parent irq for the TLMM irq_chip. | 46 | * @irq: parent irq for the TLMM irq_chip. |
47 | * @lock: Spinlock to protect register resources as well | 47 | * @lock: Spinlock to protect register resources as well |
48 | * as msm_pinctrl data structures. | 48 | * as msm_pinctrl data structures. |
@@ -56,6 +56,7 @@ struct msm_pinctrl { | |||
56 | struct device *dev; | 56 | struct device *dev; |
57 | struct pinctrl_dev *pctrl; | 57 | struct pinctrl_dev *pctrl; |
58 | struct gpio_chip chip; | 58 | struct gpio_chip chip; |
59 | struct notifier_block restart_nb; | ||
59 | int irq; | 60 | int irq; |
60 | 61 | ||
61 | spinlock_t lock; | 62 | spinlock_t lock; |
@@ -852,13 +853,14 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl) | |||
852 | return 0; | 853 | return 0; |
853 | } | 854 | } |
854 | 855 | ||
855 | #ifdef CONFIG_ARM | 856 | static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action, |
856 | static void __iomem *msm_ps_hold; | 857 | void *data) |
857 | |||
858 | static void msm_reset(enum reboot_mode reboot_mode, const char *cmd) | ||
859 | { | 858 | { |
860 | writel(0, msm_ps_hold); | 859 | struct msm_pinctrl *pctrl = container_of(nb, struct msm_pinctrl, restart_nb); |
861 | mdelay(10000); | 860 | |
861 | writel(0, pctrl->regs + PS_HOLD_OFFSET); | ||
862 | mdelay(1000); | ||
863 | return NOTIFY_DONE; | ||
862 | } | 864 | } |
863 | 865 | ||
864 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) | 866 | static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) |
@@ -868,13 +870,14 @@ static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl) | |||
868 | 870 | ||
869 | for (; i <= pctrl->soc->nfunctions; i++) | 871 | for (; i <= pctrl->soc->nfunctions; i++) |
870 | if (!strcmp(func[i].name, "ps_hold")) { | 872 | if (!strcmp(func[i].name, "ps_hold")) { |
871 | msm_ps_hold = pctrl->regs + PS_HOLD_OFFSET; | 873 | pctrl->restart_nb.notifier_call = msm_ps_hold_restart; |
872 | arm_pm_restart = msm_reset; | 874 | pctrl->restart_nb.priority = 128; |
875 | if (register_restart_handler(&pctrl->restart_nb)) | ||
876 | dev_err(pctrl->dev, | ||
877 | "failed to setup restart handler.\n"); | ||
878 | break; | ||
873 | } | 879 | } |
874 | } | 880 | } |
875 | #else | ||
876 | static void msm_pinctrl_setup_pm_reset(const struct msm_pinctrl *pctrl) {} | ||
877 | #endif | ||
878 | 881 | ||
879 | int msm_pinctrl_probe(struct platform_device *pdev, | 882 | int msm_pinctrl_probe(struct platform_device *pdev, |
880 | const struct msm_pinctrl_soc_data *soc_data) | 883 | const struct msm_pinctrl_soc_data *soc_data) |
@@ -943,6 +946,8 @@ int msm_pinctrl_remove(struct platform_device *pdev) | |||
943 | 946 | ||
944 | pinctrl_unregister(pctrl->pctrl); | 947 | pinctrl_unregister(pctrl->pctrl); |
945 | 948 | ||
949 | unregister_restart_handler(&pctrl->restart_nb); | ||
950 | |||
946 | return 0; | 951 | return 0; |
947 | } | 952 | } |
948 | EXPORT_SYMBOL(msm_pinctrl_remove); | 953 | EXPORT_SYMBOL(msm_pinctrl_remove); |