summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-02-16 03:05:09 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-02-16 03:05:09 -0800
commitd3731e3536b1cc8bbe01bb7e4de7afc9e2357da9 (patch)
tree5dd8ec8ac90c6763d5a4dcc902549bd71c2cd6d7
parent94721ff23623e11d4fd899618d7a6183f4738d28 (diff)
parentf4f685f3973a0c77bfaa26d123d743905a1ca6c2 (diff)
Merge "pinctrl: qcom: Add syscore system suspend/resume"
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.c56
-rw-r--r--drivers/pinctrl/qcom/pinctrl-msm.h1
2 files changed, 55 insertions, 2 deletions
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
index 8e585aefebf2..c1448955d3ed 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.c
+++ b/drivers/pinctrl/qcom/pinctrl-msm.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013, Sony Mobile Communications AB.
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
#include <linux/gpio.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
+#include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <linux/irqchip/msm-mpm-irq.h>
#include "../core.h"
@@ -70,6 +71,8 @@ struct msm_pinctrl {
void __iomem *regs;
};
+static struct msm_pinctrl *msm_pinctrl_data;
+
static inline struct msm_pinctrl *to_msm_pinctrl(struct gpio_chip *gc)
{
return container_of(gc, struct msm_pinctrl, chip);
@@ -896,6 +899,52 @@ static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl)
}
}
+#ifdef CONFIG_PM
+static int msm_pinctrl_suspend(void)
+{
+ return 0;
+}
+
+static void msm_pinctrl_resume(void)
+{
+ int i, irq;
+ u32 val;
+ unsigned long flags;
+ struct irq_desc *desc;
+ const struct msm_pingroup *g;
+ const char *name = "null";
+ struct msm_pinctrl *pctrl = msm_pinctrl_data;
+
+ if (!msm_show_resume_irq_mask)
+ return;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+ for_each_set_bit(i, pctrl->enabled_irqs, pctrl->chip.ngpio) {
+ g = &pctrl->soc->groups[i];
+ val = readl_relaxed(pctrl->regs + g->intr_status_reg);
+ if (val & BIT(g->intr_status_bit)) {
+ irq = irq_find_mapping(pctrl->chip.irqdomain, i);
+ desc = irq_to_desc(irq);
+ if (desc == NULL)
+ name = "stray irq";
+ else if (desc->action && desc->action->name)
+ name = desc->action->name;
+
+ pr_warn("%s: %d triggered %s\n", __func__, irq, name);
+ }
+ }
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+}
+#else
+#define msm_pinctrl_suspend NULL
+#define msm_pinctrl_resume NULL
+#endif
+
+static struct syscore_ops msm_pinctrl_pm_ops = {
+ .suspend = msm_pinctrl_suspend,
+ .resume = msm_pinctrl_resume,
+};
+
int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data)
{
@@ -903,7 +952,8 @@ int msm_pinctrl_probe(struct platform_device *pdev,
struct resource *res;
int ret;
- pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);
+ msm_pinctrl_data = pctrl = devm_kzalloc(&pdev->dev,
+ sizeof(*pctrl), GFP_KERNEL);
if (!pctrl) {
dev_err(&pdev->dev, "Can't allocate msm_pinctrl\n");
return -ENOMEM;
@@ -944,6 +994,7 @@ int msm_pinctrl_probe(struct platform_device *pdev,
pctrl->irq_chip_extn = &mpm_pinctrl_extn;
platform_set_drvdata(pdev, pctrl);
+ register_syscore_ops(&msm_pinctrl_pm_ops);
dev_dbg(&pdev->dev, "Probed Qualcomm pinctrl driver\n");
return 0;
@@ -958,6 +1009,7 @@ int msm_pinctrl_remove(struct platform_device *pdev)
pinctrl_unregister(pctrl->pctrl);
unregister_restart_handler(&pctrl->restart_nb);
+ unregister_syscore_ops(&msm_pinctrl_pm_ops);
return 0;
}
diff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h
index 54fdd04ce9d5..e986fdacc0bf 100644
--- a/drivers/pinctrl/qcom/pinctrl-msm.h
+++ b/drivers/pinctrl/qcom/pinctrl-msm.h
@@ -121,4 +121,5 @@ int msm_pinctrl_probe(struct platform_device *pdev,
const struct msm_pinctrl_soc_data *soc_data);
int msm_pinctrl_remove(struct platform_device *pdev);
+extern int msm_show_resume_irq_mask;
#endif