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. Change-Id: I6246871e638e761031c1d2f2b4bb1964b34bd2e5 CRs-Fixed: 1033023 Signed-off-by: Runmin Wang <runminw@codeaurora.org> Signed-off-by: Maria Yu <aiquny@codeaurora.org>
This commit is contained in:
parent
28a395c729
commit
081c1c9550
|
@ -30,6 +30,12 @@ struct gic_quirk {
|
|||
extern bool from_suspend;
|
||||
extern struct irq_chip gic_arch_extn;
|
||||
|
||||
#ifdef CONFIG_QCOM_SHOW_RESUME_IRQ
|
||||
extern int msm_show_resume_irq_mask;
|
||||
#else
|
||||
#define msm_show_resume_irq_mask 0
|
||||
#endif
|
||||
|
||||
int gic_configure_irq(unsigned int irq, unsigned int type,
|
||||
void __iomem *base, void (*sync_access)(void));
|
||||
void gic_dist_config(void __iomem *base, int gic_irqs,
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <asm/smp_plat.h>
|
||||
#include <asm/virt.h>
|
||||
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#include "irq-gic-common.h"
|
||||
|
||||
struct redist_region {
|
||||
|
@ -331,6 +333,69 @@ static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
gic_show_resume_irq(gic);
|
||||
}
|
||||
|
||||
static void gic_resume(void)
|
||||
{
|
||||
gic_resume_one(&gic_data);
|
||||
}
|
||||
|
||||
static struct syscore_ops gic_syscore_ops = {
|
||||
.suspend = gic_suspend,
|
||||
.resume = gic_resume,
|
||||
};
|
||||
|
||||
static int __init gic_init_sys(void)
|
||||
{
|
||||
register_syscore_ops(&gic_syscore_ops);
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(gic_init_sys);
|
||||
|
||||
#endif
|
||||
|
||||
static u64 gic_mpidr_to_affinity(unsigned long mpidr)
|
||||
{
|
||||
u64 aff;
|
||||
|
|
Loading…
Reference in New Issue