示例#1
0
int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
	int ret = 0;

	if (boot_option_idle_override)
		return 0;

	if (!pr)
		return -EINVAL;

	if (nocst) {
		return -ENODEV;
	}

	if (!pr->flags.power_setup_done)
		return -ENODEV;

	cpuidle_pause_and_lock();
	cpuidle_disable_device(&pr->power.dev);
	acpi_processor_get_power_info(pr);
	if (pr->flags.power) {
		acpi_processor_setup_cpuidle(pr);
		ret = cpuidle_enable_device(&pr->power.dev);
	}
	cpuidle_resume_and_unlock();

	return ret;
}
int acpi_processor_hotplug(struct acpi_processor *pr)
{
	int ret = 0;

	if (disabled_by_idle_boot_param())
		return 0;

	if (!pr)
		return -EINVAL;

	if (nocst) {
		return -ENODEV;
	}

	if (!pr->flags.power_setup_done)
		return -ENODEV;

	cpuidle_pause_and_lock();
	cpuidle_disable_device(&pr->power.dev);
	acpi_processor_get_power_info(pr);
	if (pr->flags.power) {
		acpi_processor_setup_cpuidle_cx(pr);
		ret = cpuidle_enable_device(&pr->power.dev);
	}
	cpuidle_resume_and_unlock();

	return ret;
}
示例#3
0
static int pseries_cpuidle_add_cpu_notifier(struct notifier_block *n,
			unsigned long action, void *hcpu)
{
	int hotcpu = (unsigned long)hcpu;
	struct cpuidle_device *dev =
				per_cpu(cpuidle_devices, hotcpu);

	if (dev && cpuidle_get_driver()) {
		switch (action) {
		case CPU_ONLINE:
		case CPU_ONLINE_FROZEN:
			cpuidle_pause_and_lock();
			cpuidle_enable_device(dev);
			cpuidle_resume_and_unlock();
			break;

		case CPU_DEAD:
		case CPU_DEAD_FROZEN:
			cpuidle_pause_and_lock();
			cpuidle_disable_device(dev);
			cpuidle_resume_and_unlock();
			break;

		default:
			return NOTIFY_DONE;
		}
	}
	return NOTIFY_OK;
}
int acpi_processor_hotplug(struct acpi_processor *pr)
{
	int ret = 0;
	struct cpuidle_device *dev;

	if (disabled_by_idle_boot_param())
		return 0;

	if (nocst)
		return -ENODEV;

	if (!pr->flags.power_setup_done)
		return -ENODEV;

	dev = per_cpu(acpi_cpuidle_device, pr->id);
	cpuidle_pause_and_lock();
	cpuidle_disable_device(dev);
	acpi_processor_get_power_info(pr);
	if (pr->flags.power) {
		acpi_processor_setup_cpuidle_cx(pr, dev);
		ret = cpuidle_enable_device(dev);
	}
	cpuidle_resume_and_unlock();

	return ret;
}
示例#5
0
/**
 * cpuidle_switch_governor - changes the governor
 * @gov: the new target governor
 *
 * NOTE: "gov" can be NULL to specify disabled
 * Must be called with cpuidle_lock acquired.
 */
int cpuidle_switch_governor(struct cpuidle_governor *gov)
{
	struct cpuidle_device *dev;

	if (gov == cpuidle_curr_governor)
		return 0;

	cpuidle_uninstall_idle_handler();

	if (cpuidle_curr_governor) {
		list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
			cpuidle_disable_device(dev);
		module_put(cpuidle_curr_governor->owner);
	}

	cpuidle_curr_governor = gov;

	if (gov) {
		if (!try_module_get(cpuidle_curr_governor->owner))
			return -EINVAL;
		list_for_each_entry(dev, &cpuidle_detected_devices, device_list)
			cpuidle_enable_device(dev);
		cpuidle_install_idle_handler();
		printk(KERN_INFO "cpuidle: using governor %s\n", gov->name);
	}

	return 0;
}
示例#6
0
文件: cpuidle.c 项目: Tigrouzen/k1099
/**
 * 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;

}
int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
	int cpu;
	struct acpi_processor *_pr;
	struct cpuidle_device *dev;

	if (disabled_by_idle_boot_param())
		return 0;

	if (!pr)
		return -EINVAL;

	if (nocst)
		return -ENODEV;

	if (!pr->flags.power_setup_done)
		return -ENODEV;

	/*
	 * FIXME:  Design the ACPI notification to make it once per
	 * system instead of once per-cpu.  This condition is a hack
	 * to make the code that updates C-States be called once.
	 */

	if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {

		cpuidle_pause_and_lock();
		/* Protect against cpu-hotplug */
		get_online_cpus();

		/* Disable all cpuidle devices */
		for_each_online_cpu(cpu) {
			_pr = per_cpu(processors, cpu);
			if (!_pr || !_pr->flags.power_setup_done)
				continue;
			dev = per_cpu(acpi_cpuidle_device, cpu);
			cpuidle_disable_device(dev);
		}

		/* Populate Updated C-state information */
		acpi_processor_get_power_info(pr);
		acpi_processor_setup_cpuidle_states(pr);

		/* Enable all cpuidle devices */
		for_each_online_cpu(cpu) {
			_pr = per_cpu(processors, cpu);
			if (!_pr || !_pr->flags.power_setup_done)
				continue;
			acpi_processor_get_power_info(_pr);
			if (_pr->flags.power) {
				dev = per_cpu(acpi_cpuidle_device, cpu);
				acpi_processor_setup_cpuidle_cx(_pr, dev);
				cpuidle_enable_device(dev);
			}
		}
		put_online_cpus();
		cpuidle_resume_and_unlock();
	}
int pseries_notify_cpuidle_add_cpu(int cpu)
{
	struct cpuidle_device *dev =
			per_cpu_ptr(pseries_cpuidle_devices, cpu);
	if (dev && cpuidle_get_driver()) {
		cpuidle_disable_device(dev);
		cpuidle_enable_device(dev);
	}
	return 0;
}
示例#9
0
文件: cpuidle.c 项目: Arakmar/G3MOD
int s5p6442_setup_lpaudio(unsigned int mode)
{
	struct cpuidle_device *device;

	int ret = 0;

	cpuidle_pause_and_lock();
	device = &per_cpu(s5p6442_cpuidle_device, smp_processor_id());
	cpuidle_disable_device(device);

	switch (mode) {
	case NORMAL_MODE:
		device->state_count = 1;
		/* Wait for interrupt state */
		device->states[0].enter = s5p6442_enter_idle_normal;
		device->states[0].exit_latency = 1;	/* uS */
		device->states[0].target_residency = 10000;
		device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
		strcpy(device->states[0].name, "IDLE");
		strcpy(device->states[0].desc, "ARM clock gating - WFI");
		break;
	case LPAUDIO_MODE:
		device->state_count = 1;
		/* Wait for interrupt state */
		device->states[0].enter = s5p6442_enter_idle_bm;
		device->states[0].exit_latency = 1;	/* uS */
		device->states[0].target_residency = 5000;
		device->states[0].flags = CPUIDLE_FLAG_TIME_VALID |
						CPUIDLE_FLAG_CHECK_BM;
		strcpy(device->states[0].name, "DEEP IDLE");
		strcpy(device->states[0].desc, "S5P6442 idle2");

		break;
	default:
		printk(KERN_ERR "Can't find cpuidle mode %d\n", mode);
		device->state_count = 1;

		/* Wait for interrupt state */
		device->states[0].enter = s5p6442_enter_idle_normal;
		device->states[0].exit_latency = 1;	/* uS */
		device->states[0].target_residency = 10000;
		device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
		strcpy(device->states[0].name, "IDLE");
		strcpy(device->states[0].desc, "ARM clock gating - WFI");
		break;
	}
	cpuidle_enable_device(device);
	cpuidle_resume_and_unlock();

	return ret;
}
int acpi_processor_cst_has_changed(struct acpi_processor *pr)
{
	int cpu;
	struct acpi_processor *_pr;

	if (disabled_by_idle_boot_param())
		return 0;

	if (!pr)
		return -EINVAL;

	if (nocst)
		return -ENODEV;

	if (!pr->flags.power_setup_done)
		return -ENODEV;


	if (pr->id == 0 && cpuidle_get_driver() == &acpi_idle_driver) {

		cpuidle_pause_and_lock();
		
		get_online_cpus();

		
		for_each_online_cpu(cpu) {
			_pr = per_cpu(processors, cpu);
			if (!_pr || !_pr->flags.power_setup_done)
				continue;
			cpuidle_disable_device(&_pr->power.dev);
		}

		
		acpi_processor_setup_cpuidle_states(pr);

		
		for_each_online_cpu(cpu) {
			_pr = per_cpu(processors, cpu);
			if (!_pr || !_pr->flags.power_setup_done)
				continue;
			acpi_processor_get_power_info(_pr);
			if (_pr->flags.power) {
				acpi_processor_setup_cpuidle_cx(_pr);
				cpuidle_enable_device(&_pr->power.dev);
			}
		}
		put_online_cpus();
		cpuidle_resume_and_unlock();
	}
示例#11
0
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;

}
示例#12
0
static int mv_cpu_idle_write(struct file *file, const char *buffer,
		unsigned long count, void *data)
{
	MV_U32	regs[4];

	/* Reading / Writing from system controller internal registers */
	if (!strncmp (buffer, "enable", strlen("enable"))) {
		if(device_registered == 0) {
			device_registered = 1;
			if (cpuidle_register_device(kirkwood_cpu_idle_device)) {
				printk(KERN_ERR "mv_cpu_idle_write: Failed registering\n");
				return -EIO;
			}
		}
		cpuidle_enable_device(kirkwood_cpu_idle_device);
	} else if (!strncmp (buffer, "disable", strlen("disable"))) {
		cpuidle_disable_device(kirkwood_cpu_idle_device);
	} else if (!strncmp (buffer, "test", strlen("test"))) {

		/* Store Interrupt mask registers. */
		regs[0] = MV_REG_READ(MV_IRQ_MASK_LOW_REG);
		regs[1] = MV_REG_READ(MV_IRQ_MASK_HIGH_REG);
		regs[2] = MV_REG_READ(MV_IRQ_MASK_ERROR_REG);

		/* Disable all interrupts . */
		MV_REG_WRITE(MV_IRQ_MASK_LOW_REG, 0x0);
		MV_REG_WRITE(MV_IRQ_MASK_HIGH_REG, 0x0);
		MV_REG_WRITE(MV_IRQ_MASK_ERROR_REG, 0x0);
		
		/* Enable only the UART interrupt. */
		MV_REG_BIT_SET(MV_IRQ_MASK_HIGH_REG, 1 << (UART_IRQ_NUM(0) - 32));
		
		printk(KERN_INFO "Press any key to leave deep idle:");
		mv_kw2_cpu_idle_enter();

		/* Restore Interrupt mask registers. */
		MV_REG_WRITE(MV_IRQ_MASK_LOW_REG, regs[0]);
		MV_REG_WRITE(MV_IRQ_MASK_HIGH_REG, regs[1]);
		MV_REG_WRITE(MV_IRQ_MASK_ERROR_REG, regs[2]);
	}

	return count;
}