Skip to content

Commit

Permalink
Merge tag 'pm-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/rafael/linux-pm

Pull power management updates from Rafael Wysocki:

 - ACPI conversion to PM handling based on struct dev_pm_ops.
 - Conversion of a number of platform drivers to PM handling based on
   struct dev_pm_ops and removal of empty legacy PM callbacks from a
   couple of PCI drivers.
 - Suspend-to-both for in-kernel hibernation from Bojan Smojver.
 - cpuidle fixes and cleanups from ShuoX Liu, Daniel Lezcano and Preeti
   Murthy.
 - cpufreq bug fixes from Jonghwa Lee and Stephen Boyd.
 - Suspend and hibernate fixes from Srivatsa Bhat and Colin Cross.
 - Generic PM domains framework updates.
 - RTC CMOS wakeup signaling update from Paul Fox.
 - sparse warnings fixes from Sachin Kamat.
 - Build warnings fixes for the generic PM domains framework and PM
   sysfs code.
 - sysfs switch for printing device suspend times from Sameer Nanda.
 - Documentation fix from Oskar Schirmer.

* tag 'pm-for-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (70 commits)
  cpufreq: Fix sysfs deadlock with concurrent hotplug/frequency switch
  EXYNOS: bugfix on retrieving old_index from freqs.old
  PM / Sleep: call early resume handlers when suspend_noirq fails
  PM / QoS: Use NULL pointer instead of plain integer in qos.c
  PM / QoS: Use NULL pointer instead of plain integer in pm_qos.h
  PM / Sleep: Require CAP_BLOCK_SUSPEND to use wake_lock/wake_unlock
  PM / Sleep: Add missing static storage class specifiers in main.c
  cpuilde / ACPI: remove time from acpi_processor_cx structure
  cpuidle / ACPI: remove usage from acpi_processor_cx structure
  cpuidle / ACPI : remove latency_ticks from acpi_processor_cx structure
  rtc-cmos: report wakeups from interrupt handler
  PM / Sleep: Fix build warning in sysfs.c for CONFIG_PM_SLEEP unset
  PM / Domains: Fix build warning for CONFIG_PM_RUNTIME unset
  olpc-xo15-sci: Use struct dev_pm_ops for power management
  PM / Domains: Replace plain integer with NULL pointer in domain.c file
  PM / Domains: Add missing static storage class specifier in domain.c file
  PM / crypto / ux500: Use struct dev_pm_ops for power management
  PM / IPMI: Remove empty legacy PCI PM callbacks
  tpm_nsc: Use struct dev_pm_ops for power management
  tpm_tis: Use struct dev_pm_ops for power management
  ...
  • Loading branch information
Linus Torvalds committed Jul 22, 2012
2 parents cb47c18 + 75a4161 commit 7100e50
Show file tree
Hide file tree
Showing 65 changed files with 887 additions and 479 deletions.
13 changes: 13 additions & 0 deletions Documentation/ABI/testing/sysfs-power
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,16 @@ Description:
Reads from this file return a string consisting of the names of
wakeup sources created with the help of /sys/power/wake_lock
that are inactive at the moment, separated with spaces.

What: /sys/power/pm_print_times
Date: May 2012
Contact: Sameer Nanda <snanda@chromium.org>
Description:
The /sys/power/pm_print_times file allows user space to
control whether the time taken by devices to suspend and
resume is printed. These prints are useful for hunting down
devices that take too long to suspend or resume.

Writing a "1" enables this printing while writing a "0"
disables it. The default value is "0". Reading from this file
will display the current value.
9 changes: 5 additions & 4 deletions Documentation/power/devices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,10 @@ for the given device during all power transitions, instead of the respective
subsystem-level callbacks. Specifically, if a device's pm_domain pointer is
not NULL, the ->suspend() callback from the object pointed to by it will be
executed instead of its subsystem's (e.g. bus type's) ->suspend() callback and
anlogously for all of the remaining callbacks. In other words, power management
domain callbacks, if defined for the given device, always take precedence over
the callbacks provided by the device's subsystem (e.g. bus type).
analogously for all of the remaining callbacks. In other words, power
management domain callbacks, if defined for the given device, always take
precedence over the callbacks provided by the device's subsystem (e.g. bus
type).

The support for device power management domains is only relevant to platforms
needing to use the same device driver power management callbacks in many
Expand All @@ -598,7 +599,7 @@ it into account in any way.
Device Low Power (suspend) States
---------------------------------
Device low-power states aren't standard. One device might only handle
"on" and "off, while another might support a dozen different versions of
"on" and "off", while another might support a dozen different versions of
"on" (how many engines are active?), plus a state that gets back to "on"
faster than from a full "off".

Expand Down
5 changes: 5 additions & 0 deletions Documentation/power/swsusp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ echo shutdown > /sys/power/disk; echo disk > /sys/power/state

echo platform > /sys/power/disk; echo disk > /sys/power/state

. If you would like to write hibernation image to swap and then suspend
to RAM (provided your platform supports it), you can try

echo suspend > /sys/power/disk; echo disk > /sys/power/state

. If you have SATA disks, you'll need recent kernels with SATA suspend
support. For suspend and resume to work, make sure your disk drivers
are built into kernel -- not modules. [There's way to make
Expand Down
6 changes: 4 additions & 2 deletions arch/x86/platform/olpc/olpc-xo15-sci.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ static int xo15_sci_remove(struct acpi_device *device, int type)
return 0;
}

static int xo15_sci_resume(struct acpi_device *device)
static int xo15_sci_resume(struct device *dev)
{
/* Enable all EC events */
olpc_ec_mask_write(EC_SCI_SRC_ALL);
Expand All @@ -215,6 +215,8 @@ static int xo15_sci_resume(struct acpi_device *device)
return 0;
}

static SIMPLE_DEV_PM_OPS(xo15_sci_pm, NULL, xo15_sci_resume);

static const struct acpi_device_id xo15_sci_device_ids[] = {
{"XO15EC", 0},
{"", 0},
Expand All @@ -227,8 +229,8 @@ static struct acpi_driver xo15_sci_drv = {
.ops = {
.add = xo15_sci_add,
.remove = xo15_sci_remove,
.resume = xo15_sci_resume,
},
.drv.pm = &xo15_sci_pm,
};

static int __init xo15_sci_init(void)
Expand Down
17 changes: 12 additions & 5 deletions drivers/acpi/ac.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file);

static int acpi_ac_add(struct acpi_device *device);
static int acpi_ac_remove(struct acpi_device *device, int type);
static int acpi_ac_resume(struct acpi_device *device);
static void acpi_ac_notify(struct acpi_device *device, u32 event);

static const struct acpi_device_id ac_device_ids[] = {
Expand All @@ -70,6 +69,9 @@ static const struct acpi_device_id ac_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, ac_device_ids);

static int acpi_ac_resume(struct device *dev);
static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);

static struct acpi_driver acpi_ac_driver = {
.name = "ac",
.class = ACPI_AC_CLASS,
Expand All @@ -78,9 +80,9 @@ static struct acpi_driver acpi_ac_driver = {
.ops = {
.add = acpi_ac_add,
.remove = acpi_ac_remove,
.resume = acpi_ac_resume,
.notify = acpi_ac_notify,
},
.drv.pm = &acpi_ac_pm,
};

struct acpi_ac {
Expand Down Expand Up @@ -309,13 +311,18 @@ static int acpi_ac_add(struct acpi_device *device)
return result;
}

static int acpi_ac_resume(struct acpi_device *device)
static int acpi_ac_resume(struct device *dev)
{
struct acpi_ac *ac;
unsigned old_state;
if (!device || !acpi_driver_data(device))

if (!dev)
return -EINVAL;
ac = acpi_driver_data(device);

ac = acpi_driver_data(to_acpi_device(dev));
if (!ac)
return -EINVAL;

old_state = ac->state;
if (acpi_ac_get_state(ac))
return 0;
Expand Down
15 changes: 11 additions & 4 deletions drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -1044,28 +1044,35 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
}

/* this is needed to learn about changes made in suspended state */
static int acpi_battery_resume(struct acpi_device *device)
static int acpi_battery_resume(struct device *dev)
{
struct acpi_battery *battery;
if (!device)

if (!dev)
return -EINVAL;
battery = acpi_driver_data(device);

battery = acpi_driver_data(to_acpi_device(dev));
if (!battery)
return -EINVAL;

battery->update_time = 0;
acpi_battery_update(battery);
return 0;
}

static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume);

static struct acpi_driver acpi_battery_driver = {
.name = "battery",
.class = ACPI_BATTERY_CLASS,
.ids = battery_device_ids,
.flags = ACPI_DRIVER_ALL_NOTIFY_EVENTS,
.ops = {
.add = acpi_battery_add,
.resume = acpi_battery_resume,
.remove = acpi_battery_remove,
.notify = acpi_battery_notify,
},
.drv.pm = &acpi_battery_pm,
};

static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
Expand Down
9 changes: 6 additions & 3 deletions drivers/acpi/button.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,19 +76,21 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);

static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device, int type);
static int acpi_button_resume(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event);

static int acpi_button_resume(struct device *dev);
static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume);

static struct acpi_driver acpi_button_driver = {
.name = "button",
.class = ACPI_BUTTON_CLASS,
.ids = button_device_ids,
.ops = {
.add = acpi_button_add,
.resume = acpi_button_resume,
.remove = acpi_button_remove,
.notify = acpi_button_notify,
},
.drv.pm = &acpi_button_pm,
};

struct acpi_button {
Expand Down Expand Up @@ -308,8 +310,9 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
}
}

static int acpi_button_resume(struct acpi_device *device)
static int acpi_button_resume(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);

if (button->type == ACPI_BUTTON_TYPE_LID)
Expand Down
21 changes: 11 additions & 10 deletions drivers/acpi/fan.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,26 @@ MODULE_LICENSE("GPL");

static int acpi_fan_add(struct acpi_device *device);
static int acpi_fan_remove(struct acpi_device *device, int type);
static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
static int acpi_fan_resume(struct acpi_device *device);

static const struct acpi_device_id fan_device_ids[] = {
{"PNP0C0B", 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, fan_device_ids);

static int acpi_fan_suspend(struct device *dev);
static int acpi_fan_resume(struct device *dev);
static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume);

static struct acpi_driver acpi_fan_driver = {
.name = "fan",
.class = ACPI_FAN_CLASS,
.ids = fan_device_ids,
.ops = {
.add = acpi_fan_add,
.remove = acpi_fan_remove,
.suspend = acpi_fan_suspend,
.resume = acpi_fan_resume,
},
.drv.pm = &acpi_fan_pm,
};

/* thermal cooling device callbacks */
Expand Down Expand Up @@ -183,24 +184,24 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
return 0;
}

static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
static int acpi_fan_suspend(struct device *dev)
{
if (!device)
if (!dev)
return -EINVAL;

acpi_bus_set_power(device->handle, ACPI_STATE_D0);
acpi_bus_set_power(to_acpi_device(dev)->handle, ACPI_STATE_D0);

return AE_OK;
}

static int acpi_fan_resume(struct acpi_device *device)
static int acpi_fan_resume(struct device *dev)
{
int result;

if (!device)
if (!dev)
return -EINVAL;

result = acpi_bus_update_power(device->handle, NULL);
result = acpi_bus_update_power(to_acpi_device(dev)->handle, NULL);
if (result)
printk(KERN_ERR PREFIX "Error updating fan power state\n");

Expand Down
12 changes: 8 additions & 4 deletions drivers/acpi/power.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,25 @@ ACPI_MODULE_NAME("power");

static int acpi_power_add(struct acpi_device *device);
static int acpi_power_remove(struct acpi_device *device, int type);
static int acpi_power_resume(struct acpi_device *device);

static const struct acpi_device_id power_device_ids[] = {
{ACPI_POWER_HID, 0},
{"", 0},
};
MODULE_DEVICE_TABLE(acpi, power_device_ids);

static int acpi_power_resume(struct device *dev);
static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume);

static struct acpi_driver acpi_power_driver = {
.name = "power",
.class = ACPI_POWER_CLASS,
.ids = power_device_ids,
.ops = {
.add = acpi_power_add,
.remove = acpi_power_remove,
.resume = acpi_power_resume,
},
.drv.pm = &acpi_power_pm,
};

/*
Expand Down Expand Up @@ -771,14 +773,16 @@ static int acpi_power_remove(struct acpi_device *device, int type)
return 0;
}

static int acpi_power_resume(struct acpi_device *device)
static int acpi_power_resume(struct device *dev)
{
int result = 0, state;
struct acpi_device *device;
struct acpi_power_resource *resource;

if (!device)
if (!dev)
return -EINVAL;

device = to_acpi_device(dev);
resource = acpi_driver_data(device);
if (!resource)
return -EINVAL;
Expand Down
13 changes: 4 additions & 9 deletions drivers/acpi/processor_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,19 @@ static const struct acpi_device_id processor_device_ids[] = {
};
MODULE_DEVICE_TABLE(acpi, processor_device_ids);

static SIMPLE_DEV_PM_OPS(acpi_processor_pm,
acpi_processor_suspend, acpi_processor_resume);

static struct acpi_driver acpi_processor_driver = {
.name = "processor",
.class = ACPI_PROCESSOR_CLASS,
.ids = processor_device_ids,
.ops = {
.add = acpi_processor_add,
.remove = acpi_processor_remove,
.suspend = acpi_processor_suspend,
.resume = acpi_processor_resume,
.notify = acpi_processor_notify,
},
.drv.pm = &acpi_processor_pm,
};

#define INSTALL_NOTIFY_HANDLER 1
Expand Down Expand Up @@ -427,18 +429,11 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
* Initialize missing things
*/
if (pr->flags.need_hotplug_init) {
struct cpuidle_driver *idle_driver =
cpuidle_get_driver();

printk(KERN_INFO "Will online and init hotplugged "
"CPU: %d\n", pr->id);
WARN(acpi_processor_start(pr), "Failed to start CPU:"
" %d\n", pr->id);
pr->flags.need_hotplug_init = 0;
if (idle_driver && !strcmp(idle_driver->name,
"intel_idle")) {
intel_idle_cpu_init(pr->id);
}
/* Normal CPU soft online event */
} else {
acpi_processor_ppc_has_changed(pr, 0);
Expand Down
Loading

0 comments on commit 7100e50

Please sign in to comment.