From bca065e876524f576da36657ffe0e7c99cc5660d Mon Sep 17 00:00:00 2001 From: Unnathi Chalicheemala Date: Tue, 5 Nov 2024 14:12:53 -0800 Subject: [PATCH] ANDROID: irqchip/irq-gic-v3: Add vendor hook for gic suspend This change adds vendor hook "android_vh_gic_v3_suspen" for gic suspend syscore ops callback. Vendor hook is invoked during deepsleep or hibernation scenarios to store gic register snapshot in downstream module. Update below functions with _v3_ to avoid naming collision: gic_dist_init() -> gic_v3_dist_init() gic_cpu_init() -> gic_v3_cpu_init() gic_dist_wait_for_rwp() -> gic_v3_dist_wait_for_rwp(). Bug: 279879797 Change-Id: I4e3729afa4daf18d73e00ee9601b6da72a578b4a Signed-off-by: Nagireddy Annem Signed-off-by: Shreyas K K Signed-off-by: Melody Olvera Signed-off-by: Unnathi Chalicheemala --- drivers/android/vendor_hooks.c | 1 + drivers/irqchip/irq-gic-v3.c | 44 ++++++++++++++++++++++++------ include/linux/irqchip/arm-gic-v3.h | 4 +++ include/trace/hooks/gic_v3.h | 4 +++ 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 964d510caa75..c6b44aa69d7d 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -129,6 +129,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_override_creds); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_revert_creds); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_mmap_file); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_file_open); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_v3_suspend); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_set_affinity); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_bpf_syscall); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery); diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 1931482bce82..0de9dd1bc2e9 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -345,10 +346,11 @@ static void gic_do_wait_for_rwp(void __iomem *base, u32 bit) } /* Wait for completion of a distributor change */ -static void gic_dist_wait_for_rwp(void) +void gic_v3_dist_wait_for_rwp(void) { gic_do_wait_for_rwp(gic_data.dist_base, GICD_CTLR_RWP); } +EXPORT_SYMBOL_GPL(gic_v3_dist_wait_for_rwp); /* Wait for completion of a redistributor change */ static void gic_redist_wait_for_rwp(void) @@ -481,7 +483,7 @@ static void gic_mask_irq(struct irq_data *d) if (gic_irq_in_rdist(d)) gic_redist_wait_for_rwp(); else - gic_dist_wait_for_rwp(); + gic_v3_dist_wait_for_rwp(); } static void gic_eoimode1_mask_irq(struct irq_data *d) @@ -961,7 +963,7 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) __gic_handle_irq_from_irqson(regs); } -static void __init gic_dist_init(void) +void __init gic_v3_dist_init(void) { unsigned int i; u64 affinity; @@ -970,7 +972,7 @@ static void __init gic_dist_init(void) /* Disable the distributor */ writel_relaxed(0, base + GICD_CTLR); - gic_dist_wait_for_rwp(); + gic_v3_dist_wait_for_rwp(); /* * Configure SPIs as non-secure Group-1. This will only matter @@ -1008,7 +1010,7 @@ static void __init gic_dist_init(void) /* Enable distributor with ARE, Group1, and wait for it to drain */ writel_relaxed(val, base + GICD_CTLR); - gic_dist_wait_for_rwp(); + gic_v3_dist_wait_for_rwp(); /* * Set all global interrupts to the boot CPU only. ARE must be @@ -1021,6 +1023,7 @@ static void __init gic_dist_init(void) for (i = 0; i < GIC_ESPI_NR; i++) gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8); } +EXPORT_SYMBOL_GPL(gic_v3_dist_init); static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *)) { @@ -1312,7 +1315,7 @@ static int gic_dist_supports_lpis(void) !gicv3_nolpi); } -static void gic_cpu_init(void) +void gic_v3_cpu_init(void) { void __iomem *rbase; int i; @@ -1340,6 +1343,7 @@ static void gic_cpu_init(void) /* initialise system registers */ gic_cpu_sys_reg_init(); } +EXPORT_SYMBOL_GPL(gic_v3_cpu_init); #ifdef CONFIG_SMP @@ -1361,7 +1365,7 @@ static int gic_check_rdist(unsigned int cpu) static int gic_starting_cpu(unsigned int cpu) { gic_cpu_sys_reg_enable(); - gic_cpu_init(); + gic_v3_cpu_init(); if (gic_dist_supports_lpis()) its_cpu_init(); @@ -1551,6 +1555,27 @@ static void gic_cpu_pm_init(void) static inline void gic_cpu_pm_init(void) { } #endif /* CONFIG_CPU_PM */ +#ifdef CONFIG_PM +static int gic_v3_suspend(void) +{ + trace_android_vh_gic_v3_suspend(&gic_data); + return 0; +} + +static struct syscore_ops gic_syscore_ops = { + .suspend = gic_v3_suspend, +}; + +static void gic_syscore_init(void) +{ + register_syscore_ops(&gic_syscore_ops); +} + +#else +static inline void gic_syscore_init(void) { } +static int gic_v3_suspend(void) { return 0; } +#endif /* CONFIG_PM */ + static struct irq_chip gic_chip = { .name = "GICv3", .irq_mask = gic_mask_irq, @@ -2104,11 +2129,12 @@ static int __init gic_init_bases(phys_addr_t dist_phys_base, gic_cpu_sys_reg_enable(); gic_prio_init(); - gic_dist_init(); - gic_cpu_init(); + gic_v3_dist_init(); + gic_v3_cpu_init(); gic_enable_nmi_support(); gic_smp_init(); gic_cpu_pm_init(); + gic_syscore_init(); if (gic_dist_supports_lpis()) { its_init(handle, &gic_data.rdists, gic_data.domain, dist_prio_irq); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 70c0948f978e..af11bff9f35c 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -656,6 +656,10 @@ static inline bool gic_enable_sre(void) return !!(val & ICC_SRE_EL1_SRE); } +void gic_v3_dist_init(void); +void gic_v3_cpu_init(void); +void gic_v3_dist_wait_for_rwp(void); + #endif #endif diff --git a/include/trace/hooks/gic_v3.h b/include/trace/hooks/gic_v3.h index 54368d65b319..8267954773eb 100644 --- a/include/trace/hooks/gic_v3.h +++ b/include/trace/hooks/gic_v3.h @@ -14,12 +14,16 @@ */ struct irq_data; struct cpumask; +struct gic_chip_data; DECLARE_RESTRICTED_HOOK(android_rvh_gic_v3_set_affinity, TP_PROTO(struct irq_data *d, const struct cpumask *mask_val, u64 *affinity, bool force, void __iomem *base, void __iomem *rbase, u64 redist_stride), TP_ARGS(d, mask_val, affinity, force, base, rbase, redist_stride), 1); +DECLARE_HOOK(android_vh_gic_v3_suspend, + TP_PROTO(struct gic_chip_data *gd), + TP_ARGS(gd)); #endif /* _TRACE_HOOK_GIC_V3_H */ /* This part must be outside protection */