diff --git a/drivers/soc/google/acpm/acpm_ipc.c b/drivers/soc/google/acpm/acpm_ipc.c index 61bb7a68da44..f554467a24fe 100644 --- a/drivers/soc/google/acpm/acpm_ipc.c +++ b/drivers/soc/google/acpm/acpm_ipc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,7 @@ static struct acpm_ipc_info *acpm_ipc; static struct workqueue_struct *update_log_wq; static struct acpm_debug_info *acpm_debug; static bool is_acpm_stop_log; +static struct cpu_irq_info *irq_info; static struct acpm_framework *acpm_initdata; static void __iomem *acpm_srambase; @@ -574,6 +576,65 @@ int acpm_ipc_send_data_sync(unsigned int channel_id, struct ipc_config *cfg) } EXPORT_SYMBOL_GPL(acpm_ipc_send_data_sync); +#ifndef arch_irq_stat +#define arch_irq_stat() 0 +#endif + +extern int nr_irqs; + +static void cpu_irq_info_dump(u32 retry) +{ + int i, cpu; + u64 sum = 0; + + for_each_possible_cpu(cpu) + sum += kstat_cpu_irqs_sum(cpu); + + sum += arch_irq_stat(); + + if (retry == 5) + pr_info("\n"); + + for_each_irq_nr(i) { + struct irq_data *data; + struct irq_desc *desc; + unsigned int irq_stat = 0, delta; + const char *name; + + data = irq_get_irq_data(i); + if (!data) + continue; + + desc = irq_data_to_desc(data); + if (!desc) + continue; + + for_each_possible_cpu(cpu) + irq_stat += *per_cpu_ptr(desc->kstat_irqs, cpu); + + if (!irq_stat) + continue; + + if (desc->action && desc->action->name) + name = desc->action->name; + else + name = "???"; + + if (retry == 1) { + irq_info[i].irq_num = i; + irq_info[i].hwirq_num = desc->irq_data.hwirq; + irq_info[i].irq_stat = irq_stat; + irq_info[i].name = name; + } else if (retry == 5) { + delta = irq_stat - irq_info[i].irq_stat; + if (delta > 0) { + pr_info("irq-%-4d(hwirq-%-3d) delta of irqs: %8u %s\n", + i, (int)desc->irq_data.hwirq, delta, name); + } + } + } +} + int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w_mode) { volatile unsigned int tx_front, tx_rear, rx_front; @@ -702,6 +763,7 @@ int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w __raw_readl(acpm_ipc->intr + INTMR1), __raw_readl(acpm_ipc->intr + INTMSR1)); + cpu_irq_info_dump(retry_cnt); ++retry_cnt; goto retry; @@ -731,7 +793,6 @@ int __acpm_ipc_send_data(unsigned int channel_id, struct ipc_config *cfg, bool w pr_err("%s Timeout error! now = %llu timeout = %llu ch:%u s:%u bitmap:%lx\n", __func__, now, timeout, channel->id, seq_num, channel->bitmap_seqnum[0]); - acpm_ramdump(); dump_stack(); dbg_snapshot_do_dpm_policy(acpm_ipc->panic_action, "acpm_ipc timeout"); @@ -1019,6 +1080,9 @@ int acpm_ipc_probe(struct platform_device *pdev) } ret = plugins_init(node); + + irq_info = kcalloc(nr_irqs, sizeof(struct cpu_irq_info), GFP_KERNEL); + dev_info(&pdev->dev, "acpm_ipc probe done.\n"); return ret; } diff --git a/drivers/soc/google/acpm/acpm_ipc.h b/drivers/soc/google/acpm/acpm_ipc.h index 3ae9f49f7c67..669f6737db21 100644 --- a/drivers/soc/google/acpm/acpm_ipc.h +++ b/drivers/soc/google/acpm/acpm_ipc.h @@ -86,6 +86,13 @@ struct acpm_debug_info { spinlock_t lock; /* generic spin-lock for debug */ }; +struct cpu_irq_info { + const char *name; + int irq_num; + unsigned long hwirq_num; + unsigned int irq_stat; +}; + #define LOG_ID_SHIFT (28) #define LOG_IS_RAW_SHIFT (27) #define LOG_IS_ERR_SHIFT (26)