/** * __cpuidle_register_device - internal register function called before register * and enable routines * @dev: the cpu * * cpuidle_lock mutex must be held before this is called */ static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); if (!try_module_get(drv->owner)) return -EINVAL; per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); ret = cpuidle_add_sysfs(dev); if (ret) goto err_sysfs; ret = cpuidle_coupled_register_device(dev); if (ret) goto err_coupled; dev->registered = 1; return 0; err_coupled: cpuidle_remove_sysfs(dev); err_sysfs: list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; module_put(drv->owner); return ret; }
/** * __cpuidle_register_device - internal register function called before register * and enable routines * @dev: the cpu * * cpuidle_lock mutex must be held before this is called */ static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct device *cpu_dev = get_cpu_device((unsigned long)dev->cpu); struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (!dev) return -EINVAL; if (!try_module_get(cpuidle_driver->owner)) return -EINVAL; init_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); ret = cpuidle_add_sysfs(cpu_dev); if (ret) goto err_sysfs; ret = cpuidle_coupled_register_device(dev); if (ret) goto err_coupled; dev->registered = 1; return 0; err_coupled: cpuidle_remove_sysfs(cpu_dev); wait_for_completion(&dev->kobj_unregister); err_sysfs: list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; module_put(cpuidle_driver->owner); return ret; }
/** * __cpuidle_register_device - internal register function called before register * and enable routines * @dev: the cpu * * cpuidle_lock mutex must be held before this is called */ static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct device *cpu_dev; struct cpuidle_driver *cpuidle_driver; if (!dev) return -EINVAL; cpu_dev = get_cpu_device((unsigned long)dev->cpu); cpuidle_driver = cpuidle_get_driver(); if (!try_module_get(cpuidle_driver->owner)) return -EINVAL; init_completion(&dev->kobj_unregister); per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); if ((ret = cpuidle_add_sysfs(cpu_dev))) { module_put(cpuidle_driver->owner); return ret; } dev->registered = 1; return 0; }
/** * cpuidle_register_device - registers a CPU's idle PM feature * @dev: the cpu */ int cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); if (!sys_dev) return -EINVAL; if (!try_module_get(cpuidle_curr_driver->owner)) return -EINVAL; init_completion(&dev->kobj_unregister); mutex_lock(&cpuidle_lock); poll_idle_init(dev); per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); if ((ret = cpuidle_add_sysfs(sys_dev))) { mutex_unlock(&cpuidle_lock); module_put(cpuidle_curr_driver->owner); return ret; } cpuidle_enable_device(dev); cpuidle_install_idle_handler(); mutex_unlock(&cpuidle_lock); return 0; }
/** * __cpuidle_register_device - internal register function called before register * and enable routines * @dev: the cpu * * cpuidle_lock mutex must be held before this is called */ static int __cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver(); if (!sys_dev) return -EINVAL; if (!try_module_get(cpuidle_driver->owner)) return -EINVAL; init_completion(&dev->kobj_unregister); /* * cpuidle driver should set the dev->power_specified bit * before registering the device if the driver provides * power_usage numbers. * * For those devices whose ->power_specified is not set, * we fill in power_usage with decreasing values as the * cpuidle code has an implicit assumption that state Cn * uses less power than C(n-1). * * With CONFIG_ARCH_HAS_CPU_RELAX, C0 is already assigned * an power value of -1. So we use -2, -3, etc, for other * c-states. */ if (!dev->power_specified) { int i; for (i = CPUIDLE_DRIVER_STATE_START; i < dev->state_count; i++) dev->states[i].power_usage = -1 - i; } per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); ret = cpuidle_add_sysfs(sys_dev); if (ret) goto err_sysfs; ret = cpuidle_coupled_register_device(dev); if (ret) goto err_coupled; dev->registered = 1; return 0; err_coupled: cpuidle_remove_sysfs(sys_dev); wait_for_completion(&dev->kobj_unregister); err_sysfs: list_del(&dev->device_list); per_cpu(cpuidle_devices, dev->cpu) = NULL; module_put(cpuidle_driver->owner); return ret; }