/* Exported to Kernel/Platform PM */ int pasr_exit(void) { enum mtkpasr_phase result; IS_MTKPASR_ENABLED; MTKPASR_START_PROFILE(); /* SR on / Disable DPD - State change: MTKPASR_ON(MTKPASR_DPD_ON) -> MTKPASR_EXITING */ result = mtkpasr_enablingSR(); MTKPASR_END_PROFILE(); if (result == MTKPASR_WRONG_STATE) { mtkpasr_err("Wrong state!\n"); goto out; } MTKPASR_START_PROFILE(); /* RAM-to-RAM decompression - State change: MTKPASR_EXITING -> MTKPASR_OFF */ result = mtkpasr_exiting(); MTKPASR_END_PROFILE(); if (result == MTKPASR_WRONG_STATE) { mtkpasr_err("Wrong state!\n"); } else if (result == MTKPASR_FAIL) { printk(KERN_ERR"\n\n\n Some Fatal Error! \n\n\n"); } out: return 0; }
/* Hook to Linux PM */ void mtkpasr_phaseone_ops(void) { IS_MTKPASR_ENABLED_NORV; /* It means no need to apply this op (Simply for paging or other periodic wakeups) */ if (is_mtkpasr_triggered()) { return; } MTKPASR_START_PROFILE(); #ifdef CONFIG_MTKPASR_MAFL if (mtkpasr_no_phaseone_ops()) goto no_phaseone; #endif mtkpasr_info("\n"); /* Drop cache - linux/mm.h */ drop_pagecache(); #ifdef CONFIG_MTKPASR_MAFL no_phaseone: #endif MTKPASR_END_PROFILE(); }
/* Hook to Linux PM */ void mtkpasr_phaseone_ops(void) { MTKPASR_START_PROFILE(); #ifdef CONFIG_MTKPASR_MAFL if (mtkpasr_no_phaseone_ops()) goto no_phaseone; #endif mtkpasr_info("\n"); /* Drop cache - linux/mm.h */ drop_pagecache(); #ifdef CONFIG_MTKPASR_MAFL no_phaseone: #endif MTKPASR_END_PROFILE(); }
/* Hook to Linux PM */ void mtkpasr_phaseone_ops(void) { struct wd_api *wd_api = NULL; /* To restart wdt */ if (get_wd_api(&wd_api) == 0) { mtkpasr_log("PASR kicks WDT!\n"); wd_api->wd_restart(WD_TYPE_NORMAL); } IS_MTKPASR_ENABLED_NORV; /* It means no need to apply this op (Simply for paging or other periodic wakeups) */ if (is_mtkpasr_triggered()) { return; } MTKPASR_START_PROFILE(); /* It will go to MTKPASR stage */ current->flags |= PF_MTKPASR; /* Inform all other memory pools to release their memory */ try_to_shrink_slab(); /* It will leave MTKPASR stage */ current->flags &= ~PF_MTKPASR; #ifdef CONFIG_MTKPASR_MAFL if (mtkpasr_no_phaseone_ops()) goto no_phaseone; #endif mtkpasr_info("\n"); /* Drop cache - linux/mm.h */ drop_pagecache(); #ifdef CONFIG_MTKPASR_MAFL no_phaseone: #endif MTKPASR_END_PROFILE(); }
/* * Exported to Kernel/Platform PM - * It will fail only when some pending wakeup source is detected. * This op may enable irq, so we should recover it if needed. */ int pasr_enter(u32 *sr, u32 *dpd) { enum mtkpasr_phase result; int ret = 0; int irq_disabled = 0; /* MTKPASR_FLUSH -> drain_all_pages -> on_each_cpu_mask will enable local irq */ IS_MTKPASR_ENABLED; /* Check whether we are in irq-disabled environment */ if (irqs_disabled()) { irq_disabled = 1; } ++mtkpasr_triggered; /* It will go to MTKPASR stage */ current->flags |= PF_MTKPASR | PF_SWAPWRITE; MTKPASR_START_PROFILE(); /* RAM-to-RAM compression - State change: MTKPASR_OFF -> MTKPASR_ENTERING -> MTKPASR_DISABLINGSR */ result = mtkpasr_entering(); MTKPASR_END_PROFILE(); /* It will leave MTKPASR stage */ current->flags &= ~(PF_MTKPASR | PF_SWAPWRITE); /* Any pending wakeup source? */ if (result == MTKPASR_GET_WAKEUP) { mtkpasr_restoring(); mtkpasr_err("PM: Failed to enter MTKPASR\n"); ++failed_mtkpasr; ret = -1; goto out; } else if (result == MTKPASR_WRONG_STATE) { mtkpasr_reset_state(); mtkpasr_err("Wrong state!\n"); ++failed_mtkpasr; goto out; } MTKPASR_START_PROFILE(); /* SR-Off/DPD - Check which banks/ranks can enter PASR/DPD - State change:MTKPASR_DISABLINGSR -> MTKPASR_ON (-> MTKPASR_DPD_ON) */ result = mtkpasr_disablingSR(sr, dpd); mtkpasr_sroff = *sr; mtkpasr_dpd = *dpd; MTKPASR_END_PROFILE(); /* To mask some banks */ set_mtkpasr_triggered(); *sr = *sr & mtkpasr_control; if (result == MTKPASR_GET_WAKEUP) { mtkpasr_restoring(); mtkpasr_err("PM: Failed to enter SR_OFF/DPD\n"); ++failed_mtkpasr; ret = -1; goto out; } else if (result == MTKPASR_WRONG_STATE) { mtkpasr_reset_state(); mtkpasr_err("Wrong state!\n"); ++failed_mtkpasr; } out: /* Recover it to irq-disabled environment if needed */ if (irq_disabled == 1) { if (!irqs_disabled()) { mtkpasr_log("IRQ is enabled! To disable it here!\n"); arch_suspend_disable_irqs(); } } return ret; }