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 <quic_nannem@quicinc.com>
Signed-off-by: Shreyas K K <quic_shrekk@quicinc.com>
Signed-off-by: Melody Olvera <quic_molvera@quicinc.com>
Signed-off-by: Unnathi Chalicheemala <quic_uchalich@quicinc.com>
This commit is contained in:
Unnathi Chalicheemala
2024-11-05 14:12:53 -08:00
committed by Todd Kjos
parent eff3d84d46
commit bca065e876
4 changed files with 44 additions and 9 deletions
+1
View File
@@ -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_rvh_revert_creds);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_mmap_file); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_mmap_file);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_file_open); 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_gic_set_affinity);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_bpf_syscall); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_bpf_syscall);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery);
+35 -9
View File
@@ -20,6 +20,7 @@
#include <linux/percpu.h> #include <linux/percpu.h>
#include <linux/refcount.h> #include <linux/refcount.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <linux/iopoll.h> #include <linux/iopoll.h>
#include <trace/hooks/gic_v3.h> #include <trace/hooks/gic_v3.h>
@@ -345,10 +346,11 @@ static void gic_do_wait_for_rwp(void __iomem *base, u32 bit)
} }
/* Wait for completion of a distributor change */ /* 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); 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 */ /* Wait for completion of a redistributor change */
static void gic_redist_wait_for_rwp(void) 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)) if (gic_irq_in_rdist(d))
gic_redist_wait_for_rwp(); gic_redist_wait_for_rwp();
else else
gic_dist_wait_for_rwp(); gic_v3_dist_wait_for_rwp();
} }
static void gic_eoimode1_mask_irq(struct irq_data *d) 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); __gic_handle_irq_from_irqson(regs);
} }
static void __init gic_dist_init(void) void __init gic_v3_dist_init(void)
{ {
unsigned int i; unsigned int i;
u64 affinity; u64 affinity;
@@ -970,7 +972,7 @@ static void __init gic_dist_init(void)
/* Disable the distributor */ /* Disable the distributor */
writel_relaxed(0, base + GICD_CTLR); 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 * 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 */ /* Enable distributor with ARE, Group1, and wait for it to drain */
writel_relaxed(val, base + GICD_CTLR); 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 * 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++) for (i = 0; i < GIC_ESPI_NR; i++)
gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8); 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 *)) 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); !gicv3_nolpi);
} }
static void gic_cpu_init(void) void gic_v3_cpu_init(void)
{ {
void __iomem *rbase; void __iomem *rbase;
int i; int i;
@@ -1340,6 +1343,7 @@ static void gic_cpu_init(void)
/* initialise system registers */ /* initialise system registers */
gic_cpu_sys_reg_init(); gic_cpu_sys_reg_init();
} }
EXPORT_SYMBOL_GPL(gic_v3_cpu_init);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
@@ -1361,7 +1365,7 @@ static int gic_check_rdist(unsigned int cpu)
static int gic_starting_cpu(unsigned int cpu) static int gic_starting_cpu(unsigned int cpu)
{ {
gic_cpu_sys_reg_enable(); gic_cpu_sys_reg_enable();
gic_cpu_init(); gic_v3_cpu_init();
if (gic_dist_supports_lpis()) if (gic_dist_supports_lpis())
its_cpu_init(); its_cpu_init();
@@ -1551,6 +1555,27 @@ static void gic_cpu_pm_init(void)
static inline void gic_cpu_pm_init(void) { } static inline void gic_cpu_pm_init(void) { }
#endif /* CONFIG_CPU_PM */ #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 = { static struct irq_chip gic_chip = {
.name = "GICv3", .name = "GICv3",
.irq_mask = gic_mask_irq, .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_cpu_sys_reg_enable();
gic_prio_init(); gic_prio_init();
gic_dist_init(); gic_v3_dist_init();
gic_cpu_init(); gic_v3_cpu_init();
gic_enable_nmi_support(); gic_enable_nmi_support();
gic_smp_init(); gic_smp_init();
gic_cpu_pm_init(); gic_cpu_pm_init();
gic_syscore_init();
if (gic_dist_supports_lpis()) { if (gic_dist_supports_lpis()) {
its_init(handle, &gic_data.rdists, gic_data.domain, dist_prio_irq); its_init(handle, &gic_data.rdists, gic_data.domain, dist_prio_irq);
+4
View File
@@ -656,6 +656,10 @@ static inline bool gic_enable_sre(void)
return !!(val & ICC_SRE_EL1_SRE); 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
#endif #endif
+4
View File
@@ -14,12 +14,16 @@
*/ */
struct irq_data; struct irq_data;
struct cpumask; struct cpumask;
struct gic_chip_data;
DECLARE_RESTRICTED_HOOK(android_rvh_gic_v3_set_affinity, DECLARE_RESTRICTED_HOOK(android_rvh_gic_v3_set_affinity,
TP_PROTO(struct irq_data *d, const struct cpumask *mask_val, TP_PROTO(struct irq_data *d, const struct cpumask *mask_val,
u64 *affinity, bool force, void __iomem *base, u64 *affinity, bool force, void __iomem *base,
void __iomem *rbase, u64 redist_stride), void __iomem *rbase, u64 redist_stride),
TP_ARGS(d, mask_val, affinity, force, base, rbase, redist_stride), TP_ARGS(d, mask_val, affinity, force, base, rbase, redist_stride),
1); 1);
DECLARE_HOOK(android_vh_gic_v3_suspend,
TP_PROTO(struct gic_chip_data *gd),
TP_ARGS(gd));
#endif /* _TRACE_HOOK_GIC_V3_H */ #endif /* _TRACE_HOOK_GIC_V3_H */
/* This part must be outside protection */ /* This part must be outside protection */