Beispiel #1
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 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;
}
Beispiel #2
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 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;
}
Beispiel #4
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;

}
Beispiel #5
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;
}