/**
 * __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;
}
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 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_unregister_device - unregisters a CPU's idle PM feature
 * @dev: the cpu
 */
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
	struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu);

	if (!sys_dev) {
		pr_err(" ERR get_cpu_sysdev returned NULL\n");
		return;
	}

	if (dev->registered == 0)
		return;

	if (!sys_dev)
		return;

	cpuidle_pause_and_lock();

	cpuidle_disable_device(dev);

	cpuidle_remove_sysfs(sys_dev);
	list_del(&dev->device_list);
	wait_for_completion(&dev->kobj_unregister);
	per_cpu(cpuidle_devices, dev->cpu) = NULL;

	cpuidle_resume_and_unlock();

	module_put(cpuidle_curr_driver->owner);
}
Beispiel #4
0
/**
 * cpuidle_unregister_device - unregisters a CPU's idle PM feature
 * @dev: the cpu
 */
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
	struct device *cpu_dev;
	struct cpuidle_driver *cpuidle_driver = cpuidle_get_driver();

	if (!dev)
		return;
	cpu_dev = get_cpu_device((unsigned long)dev->cpu);
	if (!cpu_dev)
		return;
	if (dev->registered == 0)
		return;

	cpuidle_pause_and_lock();

	cpuidle_disable_device(dev);

	cpuidle_remove_sysfs(cpu_dev);
	list_del(&dev->device_list);
	wait_for_completion(&dev->kobj_unregister);
	per_cpu(cpuidle_devices, dev->cpu) = NULL;

	cpuidle_coupled_unregister_device(dev);

	cpuidle_resume_and_unlock();

	module_put(cpuidle_driver->owner);
}
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;
}
Beispiel #6
0
/**
 * cpuidle_unregister_device - unregisters a CPU's idle PM feature
 * @dev: the cpu
 */
void cpuidle_unregister_device(struct cpuidle_device *dev)
{
	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);

	if (dev->registered == 0)
		return;

	cpuidle_pause_and_lock();

	cpuidle_disable_device(dev);

	cpuidle_remove_sysfs(dev);
	list_del(&dev->device_list);
	per_cpu(cpuidle_devices, dev->cpu) = NULL;

	cpuidle_coupled_unregister_device(dev);

	cpuidle_resume_and_unlock();

	module_put(drv->owner);
}