/** * cpuidle_enable_device - enables idle PM for a CPU * @dev: the CPU * * This function must be called between cpuidle_pause_and_lock and * cpuidle_resume_and_unlock when used externally. */ int cpuidle_enable_device(struct cpuidle_device *dev) { int ret, i; struct cpuidle_driver *drv; if (!dev) return -EINVAL; if (dev->enabled) return 0; drv = cpuidle_get_cpu_driver(dev); if (!drv || !cpuidle_curr_governor) return -EIO; if (!dev->state_count) dev->state_count = drv->state_count; if (dev->registered == 0) { ret = __cpuidle_register_device(dev); if (ret) return ret; } cpuidle_enter_ops = drv->en_core_tk_irqen ? cpuidle_enter_tk : cpuidle_enter; poll_idle_init(drv); ret = cpuidle_add_device_sysfs(dev); if (ret) return ret; if (cpuidle_curr_governor->enable && (ret = cpuidle_curr_governor->enable(drv, dev))) goto fail_sysfs; for (i = 0; i < dev->state_count; i++) { dev->states_usage[i].usage = 0; dev->states_usage[i].time = 0; } dev->last_residency = 0; smp_wmb(); dev->enabled = 1; enabled_devices++; return 0; fail_sysfs: cpuidle_remove_device_sysfs(dev); return ret; }
/** * cpuidle_enable_device - enables idle PM for a CPU * @dev: the CPU * * This function must be called between cpuidle_pause_and_lock and * cpuidle_resume_and_unlock when used externally. */ int cpuidle_enable_device(struct cpuidle_device *dev) { int ret, i; if (dev->enabled) return 0; if (!cpuidle_get_driver() || !cpuidle_curr_governor) return -EIO; if (!dev->state_count) return -EINVAL; if (dev->registered == 0) { ret = __cpuidle_register_device(dev); if (ret) return ret; } poll_idle_init(dev); if ((ret = cpuidle_add_state_sysfs(dev))) return ret; if (cpuidle_curr_governor->enable && (ret = cpuidle_curr_governor->enable(dev))) goto fail_sysfs; for (i = 0; i < dev->state_count; i++) { dev->states[i].usage = 0; dev->states[i].time = 0; } dev->last_residency = 0; dev->last_state = NULL; smp_wmb(); dev->enabled = 1; enabled_devices++; return 0; fail_sysfs: cpuidle_remove_state_sysfs(dev); return ret; }
int cpuidle_register_device(struct cpuidle_device *dev) { int ret; mutex_lock(&cpuidle_lock); if ((ret = __cpuidle_register_device(dev))) { mutex_unlock(&cpuidle_lock); return ret; } cpuidle_enable_device(dev); cpuidle_install_idle_handler(); mutex_unlock(&cpuidle_lock); return 0; }