Loading drivers/irqchip/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ config ARM_GIC_V3 select IRQ_DOMAIN_HIERARCHY select PARTITION_PERCPU select GENERIC_IRQ_EFFECTIVE_AFF_MASK select QGKI_SHOW_S2IDLE_WAKE_IRQ if QGKI config ARM_GIC_V3_ITS bool Loading Loading @@ -516,4 +517,11 @@ config SIFIVE_PLIC If you don't know what to do here, say Y. config QGKI_SHOW_S2IDLE_WAKE_IRQ bool "Qualcomm Technologies, Inc. (QTI) SHOW S2IDLE WAKE IRQ" depends on ARM_GIC_V3 help When this option is selected, first cpu waking up from s2idle prints the interrupts pending and enabled at GIC. endmenu drivers/irqchip/irq-gic-v3.c +13 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/percpu.h> #include <linux/refcount.h> #include <linux/slab.h> #include <linux/suspend.h> #include <linux/msm_rtb.h> #include <linux/wakeup_reason.h> Loading Loading @@ -604,10 +605,15 @@ static void gic_show_resume_irq(struct gic_chip_data *gic) struct irq_desc *desc = irq_to_desc(irq); const char *name = "null"; if (i < 32) continue; if (desc == NULL) name = "stray irq"; else if (desc->action && desc->action->name) name = desc->action->name; else if (desc->irq_data.chip && desc->irq_data.chip->name) name = desc->irq_data.chip->name; pr_warn("%s: irq:%d hwirq:%u triggered %s\n", __func__, irq, i, name); Loading Loading @@ -1244,6 +1250,13 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, #define gic_smp_init() do { } while(0) #endif #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ void gic_s2idle_wake(void) { gic_resume_one(&gic_data); } #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #ifdef CONFIG_CPU_PM static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) Loading include/linux/irqchip/arm-gic-v3.h +4 −0 Original line number Diff line number Diff line Loading @@ -638,6 +638,10 @@ static inline bool gic_enable_sre(void) return !!(val & ICC_SRE_EL1_SRE); } #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ void gic_s2idle_wake(void); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #endif #endif kernel/sched/idle.c +25 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ */ #include "sched.h" #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ #include <linux/irqchip/arm-gic-v3.h> #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #include <trace/events/power.h> /* Linker adds these: start and end of __cpuidle functions */ Loading Loading @@ -128,6 +131,11 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev, * set, and it returns with polling set. If it ever stops polling, it * must clear the polling bit. */ #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ static cpumask_t cpu_state; #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ static void cpuidle_idle_call(void) { struct cpuidle_device *dev = cpuidle_get_device(); Loading Loading @@ -169,9 +177,26 @@ static void cpuidle_idle_call(void) if (idle_should_enter_s2idle() || dev->use_deepest_state) { if (idle_should_enter_s2idle()) { #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ bool print_wake_irq; cpumask_set_cpu(dev->cpu, &cpu_state); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ rcu_idle_enter(); entered_state = cpuidle_enter_s2idle(drv, dev); #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ print_wake_irq = cpumask_weight(&cpu_state) == cpumask_weight(cpu_online_mask) ? true : false; cpumask_clear_cpu(dev->cpu, &cpu_state); if (print_wake_irq) gic_s2idle_wake(); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ if (entered_state > 0) { local_irq_enable(); goto exit_idle; Loading Loading
drivers/irqchip/Kconfig +8 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ config ARM_GIC_V3 select IRQ_DOMAIN_HIERARCHY select PARTITION_PERCPU select GENERIC_IRQ_EFFECTIVE_AFF_MASK select QGKI_SHOW_S2IDLE_WAKE_IRQ if QGKI config ARM_GIC_V3_ITS bool Loading Loading @@ -516,4 +517,11 @@ config SIFIVE_PLIC If you don't know what to do here, say Y. config QGKI_SHOW_S2IDLE_WAKE_IRQ bool "Qualcomm Technologies, Inc. (QTI) SHOW S2IDLE WAKE IRQ" depends on ARM_GIC_V3 help When this option is selected, first cpu waking up from s2idle prints the interrupts pending and enabled at GIC. endmenu
drivers/irqchip/irq-gic-v3.c +13 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <linux/percpu.h> #include <linux/refcount.h> #include <linux/slab.h> #include <linux/suspend.h> #include <linux/msm_rtb.h> #include <linux/wakeup_reason.h> Loading Loading @@ -604,10 +605,15 @@ static void gic_show_resume_irq(struct gic_chip_data *gic) struct irq_desc *desc = irq_to_desc(irq); const char *name = "null"; if (i < 32) continue; if (desc == NULL) name = "stray irq"; else if (desc->action && desc->action->name) name = desc->action->name; else if (desc->irq_data.chip && desc->irq_data.chip->name) name = desc->irq_data.chip->name; pr_warn("%s: irq:%d hwirq:%u triggered %s\n", __func__, irq, i, name); Loading Loading @@ -1244,6 +1250,13 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, #define gic_smp_init() do { } while(0) #endif #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ void gic_s2idle_wake(void) { gic_resume_one(&gic_data); } #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #ifdef CONFIG_CPU_PM static int gic_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd, void *v) Loading
include/linux/irqchip/arm-gic-v3.h +4 −0 Original line number Diff line number Diff line Loading @@ -638,6 +638,10 @@ static inline bool gic_enable_sre(void) return !!(val & ICC_SRE_EL1_SRE); } #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ void gic_s2idle_wake(void); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #endif #endif
kernel/sched/idle.c +25 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,9 @@ */ #include "sched.h" #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ #include <linux/irqchip/arm-gic-v3.h> #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ #include <trace/events/power.h> /* Linker adds these: start and end of __cpuidle functions */ Loading Loading @@ -128,6 +131,11 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev, * set, and it returns with polling set. If it ever stops polling, it * must clear the polling bit. */ #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ static cpumask_t cpu_state; #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ static void cpuidle_idle_call(void) { struct cpuidle_device *dev = cpuidle_get_device(); Loading Loading @@ -169,9 +177,26 @@ static void cpuidle_idle_call(void) if (idle_should_enter_s2idle() || dev->use_deepest_state) { if (idle_should_enter_s2idle()) { #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ bool print_wake_irq; cpumask_set_cpu(dev->cpu, &cpu_state); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ rcu_idle_enter(); entered_state = cpuidle_enter_s2idle(drv, dev); #ifdef CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ print_wake_irq = cpumask_weight(&cpu_state) == cpumask_weight(cpu_online_mask) ? true : false; cpumask_clear_cpu(dev->cpu, &cpu_state); if (print_wake_irq) gic_s2idle_wake(); #endif /* CONFIG_QGKI_SHOW_S2IDLE_WAKE_IRQ */ if (entered_state > 0) { local_irq_enable(); goto exit_idle; Loading