static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) { int i; for (i = 0; i < MAX_GIC_NR; i++) { switch (cmd) { case CPU_PM_ENTER: gic_cpu_save(i); break; case CPU_PM_ENTER_FAILED: case CPU_PM_EXIT: gic_cpu_restore(i); break; case CPU_CLUSTER_PM_ENTER: gic_dist_save(i); break; case CPU_CLUSTER_PM_ENTER_FAILED: case CPU_CLUSTER_PM_EXIT: gic_dist_restore(i); break; } } return NOTIFY_OK; }
/******************************************************************************* * FVP handler called when an affinity instance has just been powered on after * having been suspended earlier. The level and mpidr determine the affinity * instance. * TODO: At the moment we reuse the on finisher and reinitialize the secure * context. Need to implement a separate suspend finisher. ******************************************************************************/ int plat_affinst_suspend_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state) { if (afflvl >= MPIDR_AFFLVL2) { plat_restore_el3_dormant_data(); gic_setup(); gic_dist_restore(); } return plat_affinst_on_finish(mpidr, afflvl, state); }
static int gic_runtime_resume(struct device *dev) { struct gic_chip_data *gic = dev_get_drvdata(dev); int ret; ret = pm_clk_resume(dev); if (ret) return ret; /* * On the very first resume, the pointer to the driver data * will be NULL and this is intentional, because we do not * want to restore the GIC on the very first resume. So if * the pointer is not valid just return. */ if (!gic) return 0; gic_dist_restore(gic); gic_cpu_restore(gic); return 0; }
/******************************************************************************* * MTK_platform handler called when an affinity instance has just been powered on after * having been suspended earlier. The level and mpidr determine the affinity * instance. * TODO: At the moment we reuse the on finisher and reinitialize the secure * context. Need to implement a separate suspend finisher. ******************************************************************************/ int mt_affinst_suspend_finish(unsigned long mpidr, unsigned int afflvl, unsigned int state) { int rc = PSCI_E_SUCCESS; switch (afflvl) { case MPIDR_AFFLVL2: if (state == PSCI_STATE_OFF) { struct _el3_dormant_data *p = &el3_dormant_data[0]; if (p->mp0_l2actlr_el1 == 0 && p->mp0_l2ectlr_el1==0) panic(); write_l2actlr(p->mp0_l2actlr_el1); write_l2ectlr(p->mp0_l2ectlr_el1); //restore L2RSTDIRSABLE mmio_write_32(MP0_CA7L_CACHE_CONFIG, (mmio_read_32(MP0_CA7L_CACHE_CONFIG) & ~L2RSTDISABLE) | (p->mp0_l2rstdisable & L2RSTDISABLE)); gic_setup(); gic_dist_restore(); } break; case MPIDR_AFFLVL1: case MPIDR_AFFLVL0: return mt_affinst_on_finish(mpidr, afflvl, state); default: assert(0); } return rc; }