Merge "arm64: config: Enable show resume IRQs driver for pineapple"

This commit is contained in:
qctecmdr 2022-10-25 18:31:44 -07:00 committed by Gerrit - the friendly Code Review server
commit def15f5022
4 changed files with 134 additions and 0 deletions

View File

@ -126,6 +126,7 @@ CONFIG_QCOM_RUN_QUEUE_STATS=m
CONFIG_QCOM_SCM=m
# CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT is not set
CONFIG_QCOM_SECURE_BUFFER=m
CONFIG_QCOM_SHOW_RESUME_IRQ=m
CONFIG_QCOM_SMEM=m
CONFIG_QCOM_SMP2P=m
CONFIG_QCOM_SMP2P_SLEEPSTATE=m

View File

@ -440,6 +440,16 @@ config QCOM_PDC
Power Domain Controller driver to manage and configure wakeup
IRQs for Qualcomm Technologies Inc (QTI) mobile chips.
config QCOM_SHOW_RESUME_IRQ
tristate "Enable logging of interrupts that could have caused resume"
depends on PM
depends on ARM_GIC_V2 || ARM_GIC_V3
help
This option logs wake up interrupts that have triggered just before
the resume loop unrolls. It helps to debug to know any unnecessary
wake up interrupts that causes system to come out of low power modes.
Say Y if you want to debug why the system resumed.
config QCOM_MPM
tristate "QCOM MPM"
depends on ARCH_QCOM

View File

@ -120,3 +120,4 @@ obj-$(CONFIG_IRQ_IDT3243X) += irq-idt3243x.o
obj-$(CONFIG_APPLE_AIC) += irq-apple-aic.o
obj-$(CONFIG_MCHP_EIC) += irq-mchp-eic.o
obj-$(CONFIG_SUNPLUS_SP7021_INTC) += irq-sp7021-intc.o
obj-$(CONFIG_QCOM_SHOW_RESUME_IRQ) += msm_show_resume_irq.o

View File

@ -0,0 +1,122 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2011, 2014-2016, 2018, 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/cpuidle.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/syscore_ops.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqchip/arm-gic-v3.h>
#include <trace/hooks/cpuidle_psci.h>
static void __iomem *base;
static int msm_show_resume_irq_mask;
module_param_named(debug_mask, msm_show_resume_irq_mask, int, 0664);
static void msm_show_resume_irqs(void)
{
unsigned int i;
u32 enabled;
u32 pending[32];
u32 gic_line_nr;
u32 typer;
if (!msm_show_resume_irq_mask)
return;
typer = readl_relaxed(base + GICD_TYPER);
gic_line_nr = min(GICD_TYPER_SPIS(typer), 1023u);
for (i = 0; i * 32 < gic_line_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_line_nr);
i < gic_line_nr;
i = find_next_bit((unsigned long *)pending, gic_line_nr, i + 1)) {
if (i < 32)
continue;
pr_warn("%s: HWIRQ %u\n", __func__, i);
}
}
static atomic_t cpus_in_s2idle;
static void gic_s2idle_enter(void *unused, struct cpuidle_device *dev, bool s2idle)
{
if (!s2idle)
return;
atomic_inc(&cpus_in_s2idle);
}
static void gic_s2idle_exit(void *unused, struct cpuidle_device *dev, bool s2idle)
{
if (!s2idle)
return;
if (atomic_read(&cpus_in_s2idle) == num_online_cpus())
msm_show_resume_irqs();
atomic_dec(&cpus_in_s2idle);
}
static struct syscore_ops gic_syscore_ops = {
.resume = msm_show_resume_irqs,
};
static int msm_show_resume_probe(struct platform_device *pdev)
{
base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
if (IS_ERR(base)) {
pr_err("%pOF: unable to map GICD registers\n", pdev->dev.of_node);
return -ENXIO;
}
register_syscore_ops(&gic_syscore_ops);
return 0;
}
static const struct of_device_id msm_show_resume_match_table[] = {
{ .compatible = "qcom,show-resume-irqs" },
{ }
};
MODULE_DEVICE_TABLE(of, msm_show_resume_match_table);
static struct platform_driver msm_show_resume_dev_driver = {
.probe = msm_show_resume_probe,
.driver = {
.name = "show-resume-irqs",
.of_match_table = msm_show_resume_match_table,
},
};
static int __init msm_show_resume_init(void)
{
register_trace_prio_android_vh_cpuidle_psci_enter(gic_s2idle_enter, NULL, INT_MAX);
register_trace_prio_android_vh_cpuidle_psci_exit(gic_s2idle_exit, NULL, INT_MAX);
return platform_driver_register(&msm_show_resume_dev_driver);
}
#if IS_MODULE(CONFIG_QCOM_SHOW_RESUME_IRQ)
module_init(msm_show_resume_init);
#else
pure_initcall(msm_show_resume_init);
#endif
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Show resume IRQ");
MODULE_LICENSE("GPL");