Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c003032 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux:
  cpuidle: Single/Global registration of idle states
  cpuidle: Split cpuidle_state structure and move per-cpu statistics fields
  cpuidle: Remove CPUIDLE_FLAG_IGNORE and dev->prepare()
  cpuidle: Move dev->last_residency update to driver enter routine; remove dev->last_state
  ACPI: Fix CONFIG_ACPI_DOCK=n compiler warning
  ACPI: Export FADT pm_profile integer value to userspace
  thermal: Prevent polling from happening during system suspend
  ACPI: Drop ACPI_NO_HARDWARE_INIT
  ACPI atomicio: Convert width in bits to bytes in __acpi_ioremap_fast()
  PNPACPI: Simplify disabled resource registration
  ACPI: Fix possible recursive locking in hwregs.c
  ACPI: use kstrdup()
  mrst pmu: update comment
  tools/power turbostat: less verbose debugging
parents 83dbb15e efb90582
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
What: 		/sys/firmware/acpi/pm_profile
Date:		03-Nov-2011
KernelVersion:	v3.2
Contact:	linux-acpi@vger.kernel.org
Description: 	The ACPI pm_profile sysfs interface exports the platform
		power management (and performance) requirement expectations
		as provided by BIOS. The integer value is directly passed as
		retrieved from the FADT ACPI table.
Values:         For possible values see ACPI specification:
		5.2.9 Fixed ACPI Description Table (FADT)
		Field: Preferred_PM_Profile

		Currently these values are defined by spec:
		0 Unspecified
		1 Desktop
		2 Mobile
		3 Workstation
		4 Enterprise Server
		5 SOHO Server
		6 Appliance PC
		7 Performance Server
		>7 Reserved
+23 −18
Original line number Diff line number Diff line
@@ -34,7 +34,8 @@ static struct cpuidle_driver at91_idle_driver = {

/* Actual code that puts the SoC in different idle states */
static int at91_enter_idle(struct cpuidle_device *dev,
			       struct cpuidle_state *state)
			struct cpuidle_driver *drv,
			       int index)
{
	struct timeval before, after;
	int idle_time;
@@ -42,10 +43,10 @@ static int at91_enter_idle(struct cpuidle_device *dev,

	local_irq_disable();
	do_gettimeofday(&before);
	if (state == &dev->states[0])
	if (index == 0)
		/* Wait for interrupt state */
		cpu_do_idle();
	else if (state == &dev->states[1]) {
	else if (index == 1) {
		asm("b 1f; .align 5; 1:");
		asm("mcr p15, 0, r0, c7, c10, 4");	/* drain write buffer */
		saved_lpr = sdram_selfrefresh_enable();
@@ -56,34 +57,38 @@ static int at91_enter_idle(struct cpuidle_device *dev,
	local_irq_enable();
	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
			(after.tv_usec - before.tv_usec);
	return idle_time;

	dev->last_residency = idle_time;
	return index;
}

/* Initialize CPU idle by registering the idle states */
static int at91_init_cpuidle(void)
{
	struct cpuidle_device *device;

	cpuidle_register_driver(&at91_idle_driver);
	struct cpuidle_driver *driver = &at91_idle_driver;

	device = &per_cpu(at91_cpuidle_device, smp_processor_id());
	device->state_count = AT91_MAX_STATES;
	driver->state_count = AT91_MAX_STATES;

	/* Wait for interrupt state */
	device->states[0].enter = at91_enter_idle;
	device->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	driver->states[0].enter = at91_enter_idle;
	driver->states[0].exit_latency = 1;
	driver->states[0].target_residency = 10000;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[0].name, "WFI");
	strcpy(driver->states[0].desc, "Wait for interrupt");

	/* Wait for interrupt and RAM self refresh state */
	device->states[1].enter = at91_enter_idle;
	device->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "RAM_SR");
	strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
	driver->states[1].enter = at91_enter_idle;
	driver->states[1].exit_latency = 10;
	driver->states[1].target_residency = 10000;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[1].name, "RAM_SR");
	strcpy(driver->states[1].desc, "WFI and RAM Self Refresh");

	cpuidle_register_driver(&at91_idle_driver);

	if (cpuidle_register_device(device)) {
		printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
+29 −22
Original line number Diff line number Diff line
@@ -79,9 +79,11 @@ static struct davinci_ops davinci_states[DAVINCI_CPUIDLE_MAX_STATES] = {

/* Actual code that puts the SoC in different idle states */
static int davinci_enter_idle(struct cpuidle_device *dev,
						struct cpuidle_state *state)
				struct cpuidle_driver *drv,
						int index)
{
	struct davinci_ops *ops = cpuidle_get_statedata(state);
	struct cpuidle_state_usage *state_usage = &dev->states_usage[index];
	struct davinci_ops *ops = cpuidle_get_statedata(state_usage);
	struct timeval before, after;
	int idle_time;

@@ -99,13 +101,17 @@ static int davinci_enter_idle(struct cpuidle_device *dev,
	local_irq_enable();
	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
			(after.tv_usec - before.tv_usec);
	return idle_time;

	dev->last_residency = idle_time;

	return index;
}

static int __init davinci_cpuidle_probe(struct platform_device *pdev)
{
	int ret;
	struct cpuidle_device *device;
	struct cpuidle_driver *driver = &davinci_idle_driver;
	struct davinci_cpuidle_config *pdata = pdev->dev.platform_data;

	device = &per_cpu(davinci_cpuidle_device, smp_processor_id());
@@ -117,32 +123,33 @@ static int __init davinci_cpuidle_probe(struct platform_device *pdev)

	ddr2_reg_base = pdata->ddr2_ctlr_base;

	ret = cpuidle_register_driver(&davinci_idle_driver);
	if (ret) {
		dev_err(&pdev->dev, "failed to register driver\n");
		return ret;
	}

	/* Wait for interrupt state */
	device->states[0].enter = davinci_enter_idle;
	device->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	driver->states[0].enter = davinci_enter_idle;
	driver->states[0].exit_latency = 1;
	driver->states[0].target_residency = 10000;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[0].name, "WFI");
	strcpy(driver->states[0].desc, "Wait for interrupt");

	/* Wait for interrupt and DDR self refresh state */
	device->states[1].enter = davinci_enter_idle;
	device->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "DDR SR");
	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
	driver->states[1].enter = davinci_enter_idle;
	driver->states[1].exit_latency = 10;
	driver->states[1].target_residency = 10000;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[1].name, "DDR SR");
	strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");
	if (pdata->ddr2_pdown)
		davinci_states[1].flags |= DAVINCI_CPUIDLE_FLAGS_DDR2_PWDN;
	cpuidle_set_statedata(&device->states[1], &davinci_states[1]);
	cpuidle_set_statedata(&device->states_usage[1], &davinci_states[1]);

	device->state_count = DAVINCI_CPUIDLE_MAX_STATES;
	driver->state_count = DAVINCI_CPUIDLE_MAX_STATES;

	ret = cpuidle_register_driver(&davinci_idle_driver);
	if (ret) {
		dev_err(&pdev->dev, "failed to register driver\n");
		return ret;
	}

	ret = cpuidle_register_device(device);
	if (ret) {
+17 −13
Original line number Diff line number Diff line
@@ -16,7 +16,8 @@
#include <asm/proc-fns.h>

static int exynos4_enter_idle(struct cpuidle_device *dev,
			      struct cpuidle_state *state);
			struct cpuidle_driver *drv,
			      int index);

static struct cpuidle_state exynos4_cpuidle_set[] = {
	[0] = {
@@ -37,7 +38,8 @@ static struct cpuidle_driver exynos4_idle_driver = {
};

static int exynos4_enter_idle(struct cpuidle_device *dev,
			      struct cpuidle_state *state)
				struct cpuidle_driver *drv,
			      int index)
{
	struct timeval before, after;
	int idle_time;
@@ -52,29 +54,31 @@ static int exynos4_enter_idle(struct cpuidle_device *dev,
	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
		    (after.tv_usec - before.tv_usec);

	return idle_time;
	dev->last_residency = idle_time;
	return index;
}

static int __init exynos4_init_cpuidle(void)
{
	int i, max_cpuidle_state, cpu_id;
	struct cpuidle_device *device;
	struct cpuidle_driver *drv = &exynos4_idle_driver;

	/* Setup cpuidle driver */
	drv->state_count = (sizeof(exynos4_cpuidle_set) /
				       sizeof(struct cpuidle_state));
	max_cpuidle_state = drv->state_count;
	for (i = 0; i < max_cpuidle_state; i++) {
		memcpy(&drv->states[i], &exynos4_cpuidle_set[i],
				sizeof(struct cpuidle_state));
	}
	cpuidle_register_driver(&exynos4_idle_driver);

	for_each_cpu(cpu_id, cpu_online_mask) {
		device = &per_cpu(exynos4_cpuidle_device, cpu_id);
		device->cpu = cpu_id;

		device->state_count = (sizeof(exynos4_cpuidle_set) /
					       sizeof(struct cpuidle_state));

		max_cpuidle_state = device->state_count;

		for (i = 0; i < max_cpuidle_state; i++) {
			memcpy(&device->states[i], &exynos4_cpuidle_set[i],
					sizeof(struct cpuidle_state));
		}
		device->state_count = drv->state_count;

		if (cpuidle_register_device(device)) {
			printk(KERN_ERR "CPUidle register device failed\n,");
+24 −18
Original line number Diff line number Diff line
@@ -33,17 +33,18 @@ static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);

/* Actual code that puts the SoC in different idle states */
static int kirkwood_enter_idle(struct cpuidle_device *dev,
			       struct cpuidle_state *state)
				struct cpuidle_driver *drv,
			       int index)
{
	struct timeval before, after;
	int idle_time;

	local_irq_disable();
	do_gettimeofday(&before);
	if (state == &dev->states[0])
	if (index == 0)
		/* Wait for interrupt state */
		cpu_do_idle();
	else if (state == &dev->states[1]) {
	else if (index == 1) {
		/*
		 * Following write will put DDR in self refresh.
		 * Note that we have 256 cycles before DDR puts it
@@ -58,35 +59,40 @@ static int kirkwood_enter_idle(struct cpuidle_device *dev,
	local_irq_enable();
	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
			(after.tv_usec - before.tv_usec);
	return idle_time;

	/* Update last residency */
	dev->last_residency = idle_time;

	return index;
}

/* Initialize CPU idle by registering the idle states */
static int kirkwood_init_cpuidle(void)
{
	struct cpuidle_device *device;

	cpuidle_register_driver(&kirkwood_idle_driver);
	struct cpuidle_driver *driver = &kirkwood_idle_driver;

	device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
	device->state_count = KIRKWOOD_MAX_STATES;
	driver->state_count = KIRKWOOD_MAX_STATES;

	/* Wait for interrupt state */
	device->states[0].enter = kirkwood_enter_idle;
	device->states[0].exit_latency = 1;
	device->states[0].target_residency = 10000;
	device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[0].name, "WFI");
	strcpy(device->states[0].desc, "Wait for interrupt");
	driver->states[0].enter = kirkwood_enter_idle;
	driver->states[0].exit_latency = 1;
	driver->states[0].target_residency = 10000;
	driver->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[0].name, "WFI");
	strcpy(driver->states[0].desc, "Wait for interrupt");

	/* Wait for interrupt and DDR self refresh state */
	device->states[1].enter = kirkwood_enter_idle;
	device->states[1].exit_latency = 10;
	device->states[1].target_residency = 10000;
	device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(device->states[1].name, "DDR SR");
	strcpy(device->states[1].desc, "WFI and DDR Self Refresh");
	driver->states[1].enter = kirkwood_enter_idle;
	driver->states[1].exit_latency = 10;
	driver->states[1].target_residency = 10000;
	driver->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
	strcpy(driver->states[1].name, "DDR SR");
	strcpy(driver->states[1].desc, "WFI and DDR Self Refresh");

	cpuidle_register_driver(&kirkwood_idle_driver);
	if (cpuidle_register_device(device)) {
		printk(KERN_ERR "kirkwood_init_cpuidle: Failed registering\n");
		return -EIO;
Loading