/* Save the Interrupt controller context */
omap_intc_save_context(); /* Save the system control module context, padconf already save above*/
omap3_control_save_context();
}
staticvoid omap3_core_restore_context(void)
{ /* Restore the control module context, padconf restored by h/w */
omap3_control_restore_context(); /* Restore the interrupt controller context */
omap_intc_restore_context();
}
if (omap_type() != OMAP2_DEVICE_TYPE_GP) { /* *MPUnextstatemustbesettoPOWER_ONtemporarily, *otherwisetheWFIexecutedinsidetheROMcode *willhangthesystem.
*/
pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
ret = omap3_save_secure_ram(omap3_secure_ram_storage,
OMAP3_SAVE_SECURE_RAM_SZ);
pwrdm_set_next_pwrst(mpu_pwrdm, mpu_next_state); /* Following is for error tracking, it should not happen */ if (ret) {
pr_err("save_secure_sram() returns %08x\n", ret); while (1)
;
}
}
}
static irqreturn_t _prcm_int_handle_io(int irq, void *unused)
{ int c;
c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, OMAP3430_ST_IO_MASK |
OMAP3430_ST_IO_CHAIN_MASK);
return c ? IRQ_HANDLED : IRQ_NONE;
}
static irqreturn_t _prcm_int_handle_wakeup(int irq, void *unused)
{ int c;
/* *ClearallexceptST_IOandST_IO_CHAINforwkupmodule, *thesearehandledinaseparatehandlertoavoidacking *IOeventsbeforeparsinginmuxcode
*/
c = omap_prm_clear_mod_irqs(WKUP_MOD, 1, ~(OMAP3430_ST_IO_MASK |
OMAP3430_ST_IO_CHAIN_MASK));
c += omap_prm_clear_mod_irqs(CORE_MOD, 1, ~0);
c += omap_prm_clear_mod_irqs(OMAP3430_PER_MOD, 1, ~0); if (omap_rev() > OMAP3430_REV_ES1_0) {
c += omap_prm_clear_mod_irqs(CORE_MOD, 3, ~0);
c += omap_prm_clear_mod_irqs(OMAP3430ES2_USBHOST_MOD, 1, ~0);
}
__cpuidle void omap_sram_idle(bool rcuidle)
{ /* Variable to tell what needs to be saved and restored
* in omap_sram_idle*/ /* save_state = 0 => Nothing to save and restored */ /* save_state = 1 => Only L1 and logic lost */ /* save_state = 2 => Only L2 lost */ /* save_state = 3 => L1, L2 and logic lost */ int save_state = 0; int mpu_next_state = PWRDM_POWER_ON; int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON;
u32 sdrc_pwr = 0; int error;
mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); switch (mpu_next_state) { case PWRDM_POWER_ON: case PWRDM_POWER_RET: /* No need to save context */
save_state = 0; break; case PWRDM_POWER_OFF:
save_state = 3; break; default: /* Invalid state */
pr_err("Invalid mpu state in sram_idle\n"); return;
}
/* NEON control */ if (pwrdm_read_pwrst(neon_pwrdm) == PWRDM_POWER_ON)
pwrdm_set_next_pwrst(neon_pwrdm, mpu_next_state);
/* PER */ if (per_next_state == PWRDM_POWER_OFF)
cpu_cluster_pm_exit();
}
staticvoid omap3_pm_idle(void)
{ if (omap_irq_pending()) return;
omap3_do_wfi();
}
#ifdef CONFIG_SUSPEND staticint omap3_pm_suspend(void)
{ struct power_state *pwrst; int state, ret = 0;
/* Read current next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node)
pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm); /* Set ones wanted by suspend */
list_for_each_entry(pwrst, &pwrst_list, node) { if (omap_set_pwrdm_state(pwrst->pwrdm, pwrst->next_state)) goto restore; if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm)) goto restore;
}
omap3_intc_suspend();
omap_sram_idle(false);
restore: /* Restore next_pwrsts */
list_for_each_entry(pwrst, &pwrst_list, node) {
state = pwrdm_read_prev_pwrst(pwrst->pwrdm); if (state > pwrst->next_state) {
pr_info("Powerdomain (%s) didn't enter target state %d\n",
pwrst->pwrdm->name, pwrst->next_state);
ret = -1;
}
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
} if (ret)
pr_err("Could not enter target state in pm_suspend\n"); else
pr_info("Successfully put all powerdomains to target state\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.