pm.h 7.2 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
/*
 *  pm.h - Power management interface
 *
 *  Copyright (C) 2000 Andrew Henroid
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef _LINUX_PM_H
#define _LINUX_PM_H

#ifdef __KERNEL__

#include <linux/config.h>
#include <linux/list.h>
#include <asm/atomic.h>

/*
 * Power management requests... these are passed to pm_send_all() and friends.
 *
 * these functions are old and deprecated, see below.
 */
typedef int __bitwise pm_request_t;

#define PM_SUSPEND	((__force pm_request_t) 1)	/* enter D1-D3 */
#define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */


/*
 * Device types... these are passed to pm_register
 */
typedef int __bitwise pm_dev_t;

#define PM_UNKNOWN_DEV	((__force pm_dev_t) 0)	/* generic */
#define PM_SYS_DEV	((__force pm_dev_t) 1)	/* system device (fan, KB controller, ...) */
#define PM_PCI_DEV	((__force pm_dev_t) 2)	/* PCI device */
#define PM_USB_DEV	((__force pm_dev_t) 3)	/* USB device */
#define PM_SCSI_DEV	((__force pm_dev_t) 4)	/* SCSI device */
#define PM_ISA_DEV	((__force pm_dev_t) 5)	/* ISA device */
#define	PM_MTD_DEV	((__force pm_dev_t) 6)	/* Memory Technology Device */

/*
 * System device hardware ID (PnP) values
 */
enum
{
	PM_SYS_UNKNOWN = 0x00000000, /* generic */
	PM_SYS_KBC =	 0x41d00303, /* keyboard controller */
	PM_SYS_COM =	 0x41d00500, /* serial port */
	PM_SYS_IRDA =	 0x41d00510, /* IRDA controller */
	PM_SYS_FDC =	 0x41d00700, /* floppy controller */
	PM_SYS_VGA =	 0x41d00900, /* VGA controller */
	PM_SYS_PCMCIA =	 0x41d00e00, /* PCMCIA controller */
};

/*
 * Device identifier
 */
#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn)

/*
 * Request handler callback
 */
struct pm_dev;

typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);

/*
 * Dynamic device information
 */
struct pm_dev
{
	pm_dev_t	 type;
	unsigned long	 id;
	pm_callback	 callback;
	void		*data;

	unsigned long	 flags;
	unsigned long	 state;
	unsigned long	 prev_state;

	struct list_head entry;
};

#ifdef CONFIG_PM

extern int pm_active;

#define PM_IS_ACTIVE() (pm_active != 0)

/*
 * Register a device with power management
 */
106 107
struct pm_dev __deprecated *
pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
L
Linus Torvalds 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178

/*
 * Unregister a device with power management
 */
void __deprecated pm_unregister(struct pm_dev *dev);

/*
 * Unregister all devices with matching callback
 */
void __deprecated pm_unregister_all(pm_callback callback);

/*
 * Send a request to all devices
 */
int __deprecated pm_send_all(pm_request_t rqst, void *data);

#else /* CONFIG_PM */

#define PM_IS_ACTIVE() 0

static inline struct pm_dev *pm_register(pm_dev_t type,
					 unsigned long id,
					 pm_callback callback)
{
	return NULL;
}

static inline void pm_unregister(struct pm_dev *dev) {}

static inline void pm_unregister_all(pm_callback callback) {}

static inline int pm_send_all(pm_request_t rqst, void *data)
{
	return 0;
}

#endif /* CONFIG_PM */

/* Functions above this comment are list-based old-style power
 * managment. Please avoid using them.  */

/*
 * Callbacks for platform drivers to implement.
 */
extern void (*pm_idle)(void);
extern void (*pm_power_off)(void);

typedef int __bitwise suspend_state_t;

#define PM_SUSPEND_ON		((__force suspend_state_t) 0)
#define PM_SUSPEND_STANDBY	((__force suspend_state_t) 1)
#define PM_SUSPEND_MEM		((__force suspend_state_t) 3)
#define PM_SUSPEND_DISK		((__force suspend_state_t) 4)
#define PM_SUSPEND_MAX		((__force suspend_state_t) 5)

typedef int __bitwise suspend_disk_method_t;

#define	PM_DISK_FIRMWARE	((__force suspend_disk_method_t) 1)
#define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 2)
#define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 3)
#define	PM_DISK_REBOOT		((__force suspend_disk_method_t) 4)
#define	PM_DISK_MAX		((__force suspend_disk_method_t) 5)

struct pm_ops {
	suspend_disk_method_t pm_disk_mode;
	int (*prepare)(suspend_state_t state);
	int (*enter)(suspend_state_t state);
	int (*finish)(suspend_state_t state);
};

extern void pm_set_ops(struct pm_ops *);
A
Alexey Starikovskiy 已提交
179
extern struct pm_ops *pm_ops;
L
Linus Torvalds 已提交
180 181 182 183 184 185 186 187 188
extern int pm_suspend(suspend_state_t state);


/*
 * Device power management
 */

struct device;

189 190 191
typedef struct pm_message {
	int event;
} pm_message_t;
L
Linus Torvalds 已提交
192 193 194 195

/*
 * There are 4 important states driver can be in:
 * ON     -- driver is working
196 197 198 199 200 201 202
 * FREEZE -- stop operations and apply whatever policy is applicable to a
 *           suspended driver of that class, freeze queues for block like IDE
 *           does, drop packets for ethernet, etc... stop DMA engine too etc...
 *           so a consistent image can be saved; but do not power any hardware
 *           down.
 * SUSPEND - like FREEZE, but hardware is doing as much powersaving as
 *           possible. Roughly pci D3.
L
Linus Torvalds 已提交
203
 *
204 205 206 207
 * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
 * (SUSPEND).  We'll need to fix the drivers. So yes, putting 3 to all different
 * defines is intentional, and will go away as soon as drivers are fixed.  Also
 * note that typedef is neccessary, we'll probably want to switch to
L
Linus Torvalds 已提交
208 209 210 211
 *   typedef struct pm_message_t { int event; int flags; } pm_message_t
 * or something similar soon.
 */

212 213 214 215 216 217 218
#define PM_EVENT_ON 0
#define PM_EVENT_FREEZE 1
#define PM_EVENT_SUSPEND 2

#define PMSG_FREEZE	((struct pm_message){ .event = PM_EVENT_FREEZE, })
#define PMSG_SUSPEND	((struct pm_message){ .event = PM_EVENT_SUSPEND, })
#define PMSG_ON		((struct pm_message){ .event = PM_EVENT_ON, })
L
Linus Torvalds 已提交
219 220 221

struct dev_pm_info {
	pm_message_t		power_state;
D
David Brownell 已提交
222
	unsigned		can_wakeup:1;
L
Linus Torvalds 已提交
223
#ifdef	CONFIG_PM
D
David Brownell 已提交
224
	unsigned		should_wakeup:1;
L
Linus Torvalds 已提交
225 226 227 228 229 230 231 232 233 234 235 236 237 238
	pm_message_t		prev_state;
	void			* saved_state;
	atomic_t		pm_users;
	struct device		* pm_parent;
	struct list_head	entry;
#endif
};

extern void device_pm_set_parent(struct device * dev, struct device * parent);

extern int device_power_down(pm_message_t state);
extern void device_power_up(void);
extern void device_resume(void);

239 240
#ifdef CONFIG_PM
extern int device_suspend(pm_message_t state);
D
David Brownell 已提交
241 242 243 244 245 246 247 248

#define device_set_wakeup_enable(dev,val) \
	((dev)->power.should_wakeup = !!(val))
#define device_may_wakeup(dev) \
	(device_can_wakeup(dev) && (dev)->power.should_wakeup)

#else /* !CONFIG_PM */

249 250 251 252
static inline int device_suspend(pm_message_t state)
{
	return 0;
}
D
David Brownell 已提交
253 254 255 256

#define device_set_wakeup_enable(dev,val)	do{}while(0)
#define device_may_wakeup(dev)			(0)

257
#endif
L
Linus Torvalds 已提交
258

D
David Brownell 已提交
259 260 261 262 263 264 265 266 267 268 269
/* changes to device_may_wakeup take effect on the next pm state change.
 * by default, devices should wakeup if they can.
 */
#define device_can_wakeup(dev) \
	((dev)->power.can_wakeup)
#define device_init_wakeup(dev,val) \
	do { \
		device_can_wakeup(dev) = !!(val); \
		device_set_wakeup_enable(dev,val); \
	} while(0)

L
Linus Torvalds 已提交
270 271 272
#endif /* __KERNEL__ */

#endif /* _LINUX_PM_H */