| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * resume.c - Functions for waking devices up. | 
|  | 3 | * | 
|  | 4 | * Copyright (c) 2003 Patrick Mochel | 
|  | 5 | * Copyright (c) 2003 Open Source Development Labs | 
|  | 6 | * | 
|  | 7 | * This file is released under the GPLv2 | 
|  | 8 | * | 
|  | 9 | */ | 
|  | 10 |  | 
|  | 11 | #include <linux/device.h> | 
|  | 12 | #include "power.h" | 
|  | 13 |  | 
|  | 14 | extern int sysdev_resume(void); | 
|  | 15 |  | 
|  | 16 |  | 
|  | 17 | /** | 
|  | 18 | *	resume_device - Restore state for one device. | 
|  | 19 | *	@dev:	Device. | 
|  | 20 | * | 
|  | 21 | */ | 
|  | 22 |  | 
|  | 23 | int resume_device(struct device * dev) | 
|  | 24 | { | 
| mochel@digitalimplant.org | af70316 | 2005-03-21 10:41:04 -0800 | [diff] [blame] | 25 | int error = 0; | 
|  | 26 |  | 
|  | 27 | down(&dev->sem); | 
| David Brownell | 82428b6 | 2005-05-09 08:07:00 -0700 | [diff] [blame] | 28 | if (dev->power.pm_parent | 
|  | 29 | && dev->power.pm_parent->power.power_state) { | 
|  | 30 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", | 
|  | 31 | dev->power.power_state, | 
|  | 32 | dev->power.pm_parent->bus_id, | 
|  | 33 | dev->power.pm_parent->power.power_state); | 
|  | 34 | } | 
|  | 35 | if (dev->bus && dev->bus->resume) { | 
|  | 36 | dev_dbg(dev,"resuming\n"); | 
| mochel@digitalimplant.org | af70316 | 2005-03-21 10:41:04 -0800 | [diff] [blame] | 37 | error = dev->bus->resume(dev); | 
| David Brownell | 82428b6 | 2005-05-09 08:07:00 -0700 | [diff] [blame] | 38 | } | 
| mochel@digitalimplant.org | af70316 | 2005-03-21 10:41:04 -0800 | [diff] [blame] | 39 | up(&dev->sem); | 
|  | 40 | return error; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 41 | } | 
|  | 42 |  | 
|  | 43 |  | 
|  | 44 |  | 
|  | 45 | void dpm_resume(void) | 
|  | 46 | { | 
|  | 47 | down(&dpm_list_sem); | 
|  | 48 | while(!list_empty(&dpm_off)) { | 
|  | 49 | struct list_head * entry = dpm_off.next; | 
|  | 50 | struct device * dev = to_device(entry); | 
|  | 51 |  | 
|  | 52 | get_device(dev); | 
|  | 53 | list_del_init(entry); | 
|  | 54 | list_add_tail(entry, &dpm_active); | 
|  | 55 |  | 
|  | 56 | up(&dpm_list_sem); | 
|  | 57 | if (!dev->power.prev_state) | 
|  | 58 | resume_device(dev); | 
|  | 59 | down(&dpm_list_sem); | 
|  | 60 | put_device(dev); | 
|  | 61 | } | 
|  | 62 | up(&dpm_list_sem); | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 |  | 
|  | 66 | /** | 
|  | 67 | *	device_resume - Restore state of each device in system. | 
|  | 68 | * | 
|  | 69 | *	Walk the dpm_off list, remove each entry, resume the device, | 
|  | 70 | *	then add it to the dpm_active list. | 
|  | 71 | */ | 
|  | 72 |  | 
|  | 73 | void device_resume(void) | 
|  | 74 | { | 
|  | 75 | down(&dpm_sem); | 
|  | 76 | dpm_resume(); | 
|  | 77 | up(&dpm_sem); | 
|  | 78 | } | 
|  | 79 |  | 
|  | 80 | EXPORT_SYMBOL_GPL(device_resume); | 
|  | 81 |  | 
|  | 82 |  | 
|  | 83 | /** | 
|  | 84 | *	device_power_up_irq - Power on some devices. | 
|  | 85 | * | 
|  | 86 | *	Walk the dpm_off_irq list and power each device up. This | 
|  | 87 | *	is used for devices that required they be powered down with | 
|  | 88 | *	interrupts disabled. As devices are powered on, they are moved to | 
|  | 89 | *	the dpm_suspended list. | 
|  | 90 | * | 
|  | 91 | *	Interrupts must be disabled when calling this. | 
|  | 92 | */ | 
|  | 93 |  | 
|  | 94 | void dpm_power_up(void) | 
|  | 95 | { | 
|  | 96 | while(!list_empty(&dpm_off_irq)) { | 
|  | 97 | struct list_head * entry = dpm_off_irq.next; | 
|  | 98 | struct device * dev = to_device(entry); | 
|  | 99 |  | 
|  | 100 | get_device(dev); | 
|  | 101 | list_del_init(entry); | 
|  | 102 | list_add_tail(entry, &dpm_active); | 
|  | 103 | resume_device(dev); | 
|  | 104 | put_device(dev); | 
|  | 105 | } | 
|  | 106 | } | 
|  | 107 |  | 
|  | 108 |  | 
|  | 109 | /** | 
|  | 110 | *	device_pm_power_up - Turn on all devices that need special attention. | 
|  | 111 | * | 
|  | 112 | *	Power on system devices then devices that required we shut them down | 
|  | 113 | *	with interrupts disabled. | 
|  | 114 | *	Called with interrupts disabled. | 
|  | 115 | */ | 
|  | 116 |  | 
|  | 117 | void device_power_up(void) | 
|  | 118 | { | 
|  | 119 | sysdev_resume(); | 
|  | 120 | dpm_power_up(); | 
|  | 121 | } | 
|  | 122 |  | 
|  | 123 | EXPORT_SYMBOL_GPL(device_power_up); | 
|  | 124 |  | 
|  | 125 |  |