Skip to content

Commit

Permalink
[PATCH] properly stop devices before poweroff
Browse files Browse the repository at this point in the history
Without this patch, Linux provokes emergency disk shutdowns and
similar nastiness. It was in SuSE kernels for some time, IIRC.

Signed-off-by: Pavel Machek <pavel@suse.cz>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Pavel Machek authored and Linus Torvalds committed Jun 25, 2005
1 parent 5ce47e5 commit 620b032
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
33 changes: 21 additions & 12 deletions include/linux/pm.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ extern int pm_active;
/*
* Register a device with power management
*/
struct pm_dev __deprecated *pm_register(pm_dev_t type, unsigned long id, pm_callback callback);
struct pm_dev __deprecated *
pm_register(pm_dev_t type, unsigned long id, pm_callback callback);

/*
* Unregister a device with power management
Expand Down Expand Up @@ -190,17 +191,18 @@ typedef u32 __bitwise pm_message_t;
/*
* There are 4 important states driver can be in:
* ON -- driver is working
* 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.
* 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.
*
* 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 diferent 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
* 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
* typedef struct pm_message_t { int event; int flags; } pm_message_t
* or something similar soon.
*/
Expand All @@ -222,11 +224,18 @@ struct dev_pm_info {

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

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

#ifdef CONFIG_PM
extern int device_suspend(pm_message_t state);
#else
static inline int device_suspend(pm_message_t state)
{
return 0;
}
#endif

#endif /* __KERNEL__ */

Expand Down
3 changes: 3 additions & 0 deletions kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
case LINUX_REBOOT_CMD_HALT:
notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
system_state = SYSTEM_HALT;
device_suspend(PMSG_SUSPEND);
device_shutdown();
printk(KERN_EMERG "System halted.\n");
machine_halt();
Expand All @@ -415,6 +416,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user
case LINUX_REBOOT_CMD_POWER_OFF:
notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
system_state = SYSTEM_POWER_OFF;
device_suspend(PMSG_SUSPEND);
device_shutdown();
printk(KERN_EMERG "Power down.\n");
machine_power_off();
Expand All @@ -431,6 +433,7 @@ asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user

notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
system_state = SYSTEM_RESTART;
device_suspend(PMSG_FREEZE);
device_shutdown();
printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
machine_restart(buffer);
Expand Down

0 comments on commit 620b032

Please sign in to comment.