/* Enumeration of the various idle states this driver may enter */ enum cps_idle_state {
STATE_WAIT = 0, /* MIPS wait instruction, coherent */
STATE_NC_WAIT, /* MIPS wait instruction, non-coherent */
STATE_CLOCK_GATED, /* Core clock gated */
STATE_POWER_GATED, /* Core power gated */
STATE_COUNT
};
staticint cps_nc_enter(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index)
{ enum cps_pm_state pm_state; int err;
/* * At least one core must remain powered up & clocked in order for the * system to have any hope of functioning. * * TODO: don't treat core 0 specially, just prevent the final core * TODO: remap interrupt affinity temporarily
*/ if (cpus_are_siblings(0, dev->cpu) && (index > STATE_NC_WAIT))
index = STATE_NC_WAIT;
/* Select the appropriate cps_pm_state */ switch (index) { case STATE_NC_WAIT:
pm_state = CPS_PM_NC_WAIT; break; case STATE_CLOCK_GATED:
pm_state = CPS_PM_CLOCK_GATED; break; case STATE_POWER_GATED:
pm_state = CPS_PM_POWER_GATED; break; default:
BUG(); return -EINVAL;
}
/* Notify listeners the CPU is about to power down */ if ((pm_state == CPS_PM_POWER_GATED) && cpu_pm_enter()) return -EINTR;
/* Enter that state */
err = cps_pm_enter_state(pm_state);
/* Notify listeners the CPU is back up */ if (pm_state == CPS_PM_POWER_GATED)
cpu_pm_exit();
/* Detect supported states */ if (!cps_pm_support_state(CPS_PM_POWER_GATED))
cps_driver.state_count = STATE_CLOCK_GATED + 1; if (!cps_pm_support_state(CPS_PM_CLOCK_GATED))
cps_driver.state_count = STATE_NC_WAIT + 1; if (!cps_pm_support_state(CPS_PM_NC_WAIT))
cps_driver.state_count = STATE_WAIT + 1;
/* Inform the user if some states are unavailable */ if (cps_driver.state_count < STATE_COUNT) {
pr_info("cpuidle-cps: limited to "); switch (cps_driver.state_count - 1) { case STATE_WAIT:
pr_cont("coherent wait\n"); break; case STATE_NC_WAIT:
pr_cont("non-coherent wait\n"); break; case STATE_CLOCK_GATED:
pr_cont("clock gating\n"); break;
}
}
/* * Set the coupled flag on the appropriate states if this system * requires it.
*/ if (coupled_coherence) for (i = STATE_NC_WAIT; i < cps_driver.state_count; i++)
cps_driver.states[i].flags |= CPUIDLE_FLAG_COUPLED;
err = cpuidle_register_driver(&cps_driver); if (err) {
pr_err("Failed to register CPS cpuidle driver\n"); return err;
}
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.