summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunmin Wang <runminw@codeaurora.org>2016-06-23 11:13:24 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-29 11:09:23 -0700
commitd1a6faf956b7f4a7ce3b174c33ac26c0197a8ae0 (patch)
tree45a59de65586b5b4c6cd10fadd7aa60cde945074
parent4689ca86b64f73075e9ab6cc23d01a931d9a71c0 (diff)
drivers: GICv3: Enable logging of interrupts that triggered wakeup
This change enables logging of irq number and name which triggered wake up of the system from deep sleep. This helps in debugging the spurious wakeups due to interrupts from various subsystems. CRs-Fixed: 1033023 Change-Id: Ieeec5959475740e2b0cc75871c1f7e10e1098fa4 Signed-off-by: Runmin Wang <runminw@codeaurora.org>
-rw-r--r--drivers/irqchip/irq-gic-common.h1
-rw-r--r--drivers/irqchip/irq-gic-v3.c34
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h
index a6fceec46ba7..9fd675ddf229 100644
--- a/drivers/irqchip/irq-gic-common.h
+++ b/drivers/irqchip/irq-gic-common.h
@@ -28,6 +28,7 @@ struct gic_quirk {
};
extern bool from_suspend;
extern struct irq_chip gic_arch_extn;
+extern int msm_show_resume_irq_mask;
int gic_configure_irq(unsigned int irq, unsigned int type,
void __iomem *base, void (*sync_access)(void));
diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index d6bd0c54c005..6095bd2ccb58 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -410,11 +410,45 @@ static int gic_suspend(void)
return 0;
}
+static void gic_show_resume_irq(struct gic_chip_data *gic)
+{
+ unsigned int i;
+ u32 enabled;
+ u32 pending[32];
+ void __iomem *base = gic_data_dist_base(gic);
+
+ if (!msm_show_resume_irq_mask)
+ return;
+
+ for (i = 0; i * 32 < gic->irq_nr; i++) {
+ enabled = readl_relaxed(base + GICD_ICENABLER + i * 4);
+ pending[i] = readl_relaxed(base + GICD_ISPENDR + i * 4);
+ pending[i] &= enabled;
+ }
+
+ for (i = find_first_bit((unsigned long *)pending, gic->irq_nr);
+ i < gic->irq_nr;
+ i = find_next_bit((unsigned long *)pending, gic->irq_nr, i+1)) {
+ unsigned int irq = irq_find_mapping(gic->domain, i);
+ struct irq_desc *desc = irq_to_desc(irq);
+ const char *name = "null";
+
+ 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);
+ }
+}
+
static void gic_resume_one(struct gic_chip_data *gic)
{
unsigned int i;
void __iomem *base = gic_data_dist_base(gic);
+ gic_show_resume_irq(gic);
+
for (i = 0; i * 32 < gic->irq_nr; i++) {
/* disable all of them */
writel_relaxed(0xffffffff, base + GICD_ICENABLER + i * 4);