Home | History | Annotate | Download | only in linux
      1 /*
      2  *  pm.h - Power management interface
      3  *
      4  *  Copyright (C) 2000 Andrew Henroid
      5  *
      6  *  This program is free software; you can redistribute it and/or modify
      7  *  it under the terms of the GNU General Public License as published by
      8  *  the Free Software Foundation; either version 2 of the License, or
      9  *  (at your option) any later version.
     10  *
     11  *  This program is distributed in the hope that it will be useful,
     12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  *  GNU General Public License for more details.
     15  *
     16  *  You should have received a copy of the GNU General Public License
     17  *  along with this program; if not, write to the Free Software
     18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     19  */
     20 
     21 #ifndef _LINUX_PM_H
     22 #define _LINUX_PM_H
     23 
     24 #ifdef __KERNEL__
     25 
     26 #include <linux/list.h>
     27 #include <asm/atomic.h>
     28 
     29 /*
     30  * Power management requests... these are passed to pm_send_all() and friends.
     31  *
     32  * these functions are old and deprecated, see below.
     33  */
     34 typedef int __bitwise pm_request_t;
     35 
     36 #define PM_SUSPEND	((__force pm_request_t) 1)	/* enter D1-D3 */
     37 #define PM_RESUME	((__force pm_request_t) 2)	/* enter D0 */
     38 
     39 
     40 /*
     41  * Device types... these are passed to pm_register
     42  */
     43 typedef int __bitwise pm_dev_t;
     44 
     45 #define PM_UNKNOWN_DEV	((__force pm_dev_t) 0)	/* generic */
     46 #define PM_SYS_DEV	((__force pm_dev_t) 1)	/* system device (fan, KB controller, ...) */
     47 #define PM_PCI_DEV	((__force pm_dev_t) 2)	/* PCI device */
     48 #define PM_USB_DEV	((__force pm_dev_t) 3)	/* USB device */
     49 #define PM_SCSI_DEV	((__force pm_dev_t) 4)	/* SCSI device */
     50 #define PM_ISA_DEV	((__force pm_dev_t) 5)	/* ISA device */
     51 #define	PM_MTD_DEV	((__force pm_dev_t) 6)	/* Memory Technology Device */
     52 
     53 /*
     54  * System device hardware ID (PnP) values
     55  */
     56 enum
     57 {
     58 	PM_SYS_UNKNOWN = 0x00000000, /* generic */
     59 	PM_SYS_KBC =	 0x41d00303, /* keyboard controller */
     60 	PM_SYS_COM =	 0x41d00500, /* serial port */
     61 	PM_SYS_IRDA =	 0x41d00510, /* IRDA controller */
     62 	PM_SYS_FDC =	 0x41d00700, /* floppy controller */
     63 	PM_SYS_VGA =	 0x41d00900, /* VGA controller */
     64 	PM_SYS_PCMCIA =	 0x41d00e00, /* PCMCIA controller */
     65 };
     66 
     67 /*
     68  * Device identifier
     69  */
     70 #define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn)
     71 
     72 /*
     73  * Request handler callback
     74  */
     75 struct pm_dev;
     76 
     77 typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data);
     78 
     79 /*
     80  * Dynamic device information
     81  */
     82 struct pm_dev
     83 {
     84 	pm_dev_t	 type;
     85 	unsigned long	 id;
     86 	pm_callback	 callback;
     87 	void		*data;
     88 
     89 	unsigned long	 flags;
     90 	unsigned long	 state;
     91 	unsigned long	 prev_state;
     92 
     93 	struct list_head entry;
     94 };
     95 
     96 /* Functions above this comment are list-based old-style power
     97  * managment. Please avoid using them.  */
     98 
     99 /*
    100  * Callbacks for platform drivers to implement.
    101  */
    102 extern void (*pm_idle)(void);
    103 extern void (*pm_power_off)(void);
    104 
    105 typedef int __bitwise suspend_state_t;
    106 
    107 #define PM_SUSPEND_ON		((__force suspend_state_t) 0)
    108 #define PM_SUSPEND_STANDBY	((__force suspend_state_t) 1)
    109 #define PM_SUSPEND_MEM		((__force suspend_state_t) 3)
    110 #define PM_SUSPEND_DISK		((__force suspend_state_t) 4)
    111 #define PM_SUSPEND_MAX		((__force suspend_state_t) 5)
    112 
    113 typedef int __bitwise suspend_disk_method_t;
    114 
    115 #define	PM_DISK_FIRMWARE	((__force suspend_disk_method_t) 1)
    116 #define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 2)
    117 #define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 3)
    118 #define	PM_DISK_REBOOT		((__force suspend_disk_method_t) 4)
    119 #define	PM_DISK_MAX		((__force suspend_disk_method_t) 5)
    120 
    121 struct pm_ops {
    122 	suspend_disk_method_t pm_disk_mode;
    123 	int (*valid)(suspend_state_t state);
    124 	int (*prepare)(suspend_state_t state);
    125 	int (*enter)(suspend_state_t state);
    126 	int (*finish)(suspend_state_t state);
    127 };
    128 
    129 extern void pm_set_ops(struct pm_ops *);
    130 extern struct pm_ops *pm_ops;
    131 extern int pm_suspend(suspend_state_t state);
    132 
    133 
    134 /*
    135  * Device power management
    136  */
    137 
    138 struct device;
    139 
    140 typedef struct pm_message {
    141 	int event;
    142 } pm_message_t;
    143 
    144 /*
    145  * There are 4 important states driver can be in:
    146  * ON     -- driver is working
    147  * FREEZE -- stop operations and apply whatever policy is applicable to a
    148  *           suspended driver of that class, freeze queues for block like IDE
    149  *           does, drop packets for ethernet, etc... stop DMA engine too etc...
    150  *           so a consistent image can be saved; but do not power any hardware
    151  *           down.
    152  * SUSPEND - like FREEZE, but hardware is doing as much powersaving as
    153  *           possible. Roughly pci D3.
    154  *
    155  * Unfortunately, current drivers only recognize numeric values 0 (ON) and 3
    156  * (SUSPEND).  We'll need to fix the drivers. So yes, putting 3 to all different
    157  * defines is intentional, and will go away as soon as drivers are fixed.  Also
    158  * note that typedef is neccessary, we'll probably want to switch to
    159  *   typedef struct pm_message_t { int event; int flags; } pm_message_t
    160  * or something similar soon.
    161  */
    162 
    163 #define PM_EVENT_ON 0
    164 #define PM_EVENT_FREEZE 1
    165 #define PM_EVENT_SUSPEND 2
    166 
    167 #define PMSG_FREEZE	((struct pm_message){ .event = PM_EVENT_FREEZE, })
    168 #define PMSG_SUSPEND	((struct pm_message){ .event = PM_EVENT_SUSPEND, })
    169 #define PMSG_ON		((struct pm_message){ .event = PM_EVENT_ON, })
    170 
    171 struct dev_pm_info {
    172 	pm_message_t		power_state;
    173 	unsigned		can_wakeup:1;
    174 #ifdef	CONFIG_PM
    175 	unsigned		should_wakeup:1;
    176 	pm_message_t		prev_state;
    177 	void			* saved_state;
    178 	struct device		* pm_parent;
    179 	struct list_head	entry;
    180 #endif
    181 };
    182 
    183 extern void device_pm_set_parent(struct device * dev, struct device * parent);
    184 
    185 extern int device_power_down(pm_message_t state);
    186 extern void device_power_up(void);
    187 extern void device_resume(void);
    188 
    189 #ifdef CONFIG_PM
    190 extern suspend_disk_method_t pm_disk_mode;
    191 
    192 extern int device_suspend(pm_message_t state);
    193 
    194 #define device_set_wakeup_enable(dev,val) \
    195 	((dev)->power.should_wakeup = !!(val))
    196 #define device_may_wakeup(dev) \
    197 	(device_can_wakeup(dev) && (dev)->power.should_wakeup)
    198 
    199 extern int dpm_runtime_suspend(struct device *, pm_message_t);
    200 extern void dpm_runtime_resume(struct device *);
    201 extern void __suspend_report_result(const char *function, void *fn, int ret);
    202 
    203 #define suspend_report_result(fn, ret)					\
    204 	do {								\
    205 		__suspend_report_result(__FUNCTION__, fn, ret);		\
    206 	} while (0)
    207 
    208 #else /* !CONFIG_PM */
    209 
    210 static inline int device_suspend(pm_message_t state)
    211 {
    212 	return 0;
    213 }
    214 
    215 #define device_set_wakeup_enable(dev,val)	do{}while(0)
    216 #define device_may_wakeup(dev)			(0)
    217 
    218 static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state)
    219 {
    220 	return 0;
    221 }
    222 
    223 static inline void dpm_runtime_resume(struct device * dev)
    224 {
    225 }
    226 
    227 #define suspend_report_result(fn, ret) do { } while (0)
    228 
    229 #endif
    230 
    231 /* changes to device_may_wakeup take effect on the next pm state change.
    232  * by default, devices should wakeup if they can.
    233  */
    234 #define device_can_wakeup(dev) \
    235 	((dev)->power.can_wakeup)
    236 #define device_init_wakeup(dev,val) \
    237 	do { \
    238 		device_can_wakeup(dev) = !!(val); \
    239 		device_set_wakeup_enable(dev,val); \
    240 	} while(0)
    241 
    242 #endif /* __KERNEL__ */
    243 
    244 #endif /* _LINUX_PM_H */
    245