FYI: my current swsusp bigdiff
Subsystems (8)
Hi!
Here it is. This is FYI, not to be applied.
Pavel
%patch
drivers/input/serio/i8042.c +1 -4
@@ -432,18 +432,15 @@* desired. */ -static int __init i8042_controller_init (void ) +int i8042_controller_init (void ) { -/* * Test the i8042. We need to know if it thinks it's working correctly * before doing anything else. */ i8042_flush (); -if (i8042_reset) { -unsigned char param;if (i8042_command (¶m,I8042_CMD_CTL_TEST )) {
drivers/input/keyboard/atkbd.c +6 -5
@@ -27,7 +27,7 @@static int atkbd_set =2 ;#if defined(__i386__) || defined (__x86_64__) -static int atkbd_reset; +static int atkbd_reset =1 ;#else static int atkbd_reset =1 ;#endif
@@ -387,7 +387,7 @@* atkbd_probe() probes for an AT keyboard on a serio port. */ -static int atkbd_probe (struct atkbd *atkbd) +int atkbd_probe (struct atkbd *atkbd) {unsigned char param[2 ];
@@ -476,6 +476,9 @@kfree (atkbd); } +struct atkbd *myat; + +/* * atkbd_connect() is called when the serio module finds and interface * that isn't handled yet by an appropriate device driver. We check if
@@ -495,6 +498,7 @@if (!(atkbd =kmalloc (sizeof (struct atkbd ),GFP_KERNEL )))return ; + myat = atkbd;memset (atkbd,0 ,sizeof (struct atkbd ));if ((serio->type &SERIO_TYPE ) ==SERIO_8042 && serio->write)
@@ -523,15 +527,12 @@ }if (atkbd->write) { -if (atkbd_probe (atkbd)) {serio_close (serio);kfree (atkbd);return ; } - atkbd->set =atkbd_set_3 (atkbd); - }else { atkbd->set =2 ; atkbd->id =0xab00 ;
include/linux/serio.h +0 -4
@@ -18,10 +18,7 @@#include <linux/list.h> -struct serio ; -struct serio { -void *private;void *driver;char *name;
@@ -45,7 +42,6 @@ };struct serio_dev { -void *private;char *name;
drivers/input/power.c +12 -4
@@ -45,9 +45,7 @@static int suspend_button_pushed =0 ;static void suspend_button_task_handler (void *data) { -//extern void pm_do_suspend(void); udelay (200 );/* debounce */ -//pm_do_suspend(); suspend_button_pushed =0 ; }
@@ -67,8 +65,6 @@case KEY_SUSPEND :printk ("Powering down entire device\n" ); -//pm_send_all(PM_SUSPEND, dev); -if (!suspend_button_pushed) { suspend_button_pushed =1 ;schedule_work (&suspend_button_task);
@@ -76,6 +72,18 @@break ;case KEY_POWER :/* Hum power down the machine. */ + { +char *argv[2 ] = {NULL ,NULL }; +char *envp[3 ] = {NULL ,NULL ,NULL }; + + argv[0 ] ="/sbin/poweroff" ; + +/* minimal command environment */ + envp[0 ] ="HOME=/" ; + envp[1 ] ="PATH=/sbin:/bin:/usr/sbin:/usr/bin" ; + +call_usermodehelper (argv[0 ], argv, envp,0 ); + }break ;default :return ;
drivers/acpi/sleep/main.c +15 -5
@@ -50,6 +50,18 @@/* enable interrupts once again */ ACPI_ENABLE_IRQS (); +// i8042_controller_init(); + { +extern struct atkbd *myat; +atkbd_probe (myat); + } + +// i8042_controller_init(); + { +extern struct atkbd *myat; +atkbd_probe (myat); + } +/* restore device context */ device_resume (RESUME_RESTORE_STATE );
@@ -69,10 +81,6 @@* First, we call to the device driver layer to save device state. * Once we have that, we save whatevery processor and kernel state we * need to memory. -* If we're entering S4, we then write the memory image to disk. -* -* Only then is it safe for us to power down devices, since we may need -* the disks and upstream buses to write to. */ acpi_status acpi_system_save_state(
@@ -197,7 +205,7 @@break ; }local_irq_restore (flags); -printk (KERN_CRIT "Back to C!\n" ); +printk (KERN_DEBUG "Back to C!\n" );return status; }
@@ -226,6 +234,7 @@if (state ==ACPI_STATE_S4 && !acpi_gbl_FACS->S4bios_f)return AE_ERROR ; +prepare_suspend_console ();/* * TBD: S1 can be done without device_suspend. Make a CONFIG_XX * to handle however when S1 failed without device_suspend.
@@ -270,6 +279,7 @@/* reset firmware waking vector */ acpi_set_firmware_waking_vector ((acpi_physical_address )0 );thaw_processes (); +restore_console ();return status; }
arch/x86_64/kernel/time.c +20 -5
@@ -22,7 +22,7 @@#include <linux/time.h> #include <linux/ioport.h> #include <linux/module.h> -#include <linux/device.h> +#include <linux/sysdev.h> #include <linux/bcd.h> #include <asm/pgtable.h> #include <asm/vsyscall.h>
@@ -72,7 +72,7 @@* timer interrupt has happened already, but vxtime.trigger wasn't updated yet. * This is not a problem, because jiffies hasn't updated either. They are bound * together by xtime_lock. -*/ +*/ static inline unsigned int do_gettimeoffset_tsc (void ) {
@@ -549,7 +549,17 @@return 0 ; } -void __init pit_init (void ) +static struct sysdev_class rtc_sysclass = { +set_kset_name ("rtc" ), +}; + +/* XXX this driverfs stuff should probably go elsewhere later -john */ +static struct sys_device device_i8253 = { + .id =0 , + .cls = &rtc_sysclass, +}; + +int __init pit_init (void ) {unsigned long flags;
@@ -558,6 +568,11 @@outb_p (LATCH &0xff ,0x40 );/* LSB */ outb_p (LATCH >>8 ,0x40 );/* MSB */ spin_unlock_irqrestore (&i8253_lock, flags); + +int error =sysdev_class_register (&rtc_sysclass); +if (!error) + error =sys_device_register (&device_i8253); +return error; }int __init time_setup (char *str)
@@ -601,8 +616,8 @@ cpu_khz =hpet_calibrate_tsc (); timename ="HPET" ; }else { -pit_init (); - cpu_khz =pit_calibrate_tsc (); +pit_init (); + cpu_khz =pit_calibrate_tsc (); timename ="PIT" ; }
arch/i386/kernel/Makefile +2 -1
@@ -24,7 +24,8 @@ obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o suspend_asm.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o +obj-$(CONFIG_PM) += suspend_asm.o obj-$(CONFIG_X86_NUMAQ) += numaq.o obj-$(CONFIG_X86_SUMMIT) += summit.o obj-$(CONFIG_EDD) += edd.o
arch/i386/kernel/suspend_asm.S +2 -1
@@ -32,6 +32,7 @@ saved_context_eflags: .long 0 +#ifdef CONFIG_SOFTWARE_SUSPEND .text ENTRY(do_magic)
@@ -117,4 +118,4 @@ loop2: .quad 0 .previous - +#endif
arch/i386/kernel/sysenter.c +0 -2
@@ -31,8 +31,6 @@wrmsr (MSR_IA32_SYSENTER_CS , __KERNEL_CS,0 );wrmsr (MSR_IA32_SYSENTER_ESP , tss->esp1,0 );wrmsr (MSR_IA32_SYSENTER_EIP , (unsigned long ) sysenter_entry,0 ); - -printk ("Enabling SEP on CPU %d\n" , cpu);put_cpu (); }
drivers/acpi/Kconfig +2 -2
@@ -58,8 +58,8 @@ default y config ACPI_SLEEP - bool "Sleep States" - depends on X86 && ACPI && !ACPI_HT_ONLY && SOFTWARE_SUSPEND + bool "Sleep States (EXPERIMENTAL)" + depends on X86 && ACPI && !ACPI_HT_ONLY && EXPERIMENTAL ---help--- This option adds support for ACPI suspend states.
drivers/base/power.c +0 -6
@@ -52,8 +52,6 @@struct device * dev;int error =0 ; -printk (KERN_EMERG "Suspending devices\n" ); -down_write (&devices_subsys.rwsem);list_for_each_entry_reverse (dev,&devices_subsys.kset.list,kobj.entry) {if (dev->driver && dev->driver->suspend) {
@@ -114,8 +112,6 @@ } }up_write (&devices_subsys.rwsem); - -printk (KERN_EMERG "Devices Resumed\n" ); }/**
@@ -125,8 +121,6 @@ {struct device * dev; -printk (KERN_EMERG "Shutting down devices\n" ); -down_write (&devices_subsys.rwsem);list_for_each_entry_reverse (dev,&devices_subsys.kset.list,kobj.entry) {pr_debug ("shutting down %s: " ,dev->name);
drivers/pcmcia/yenta_socket.c +4 -1
@@ -899,7 +899,10 @@static int yenta_dev_suspend (struct pci_dev *dev,u32 state) { -return pcmcia_socket_dev_suspend (&dev->dev, state,0 ); +/* FIXME: We should really let devices to act on *all* levels :-(. +If you put something else than SUSPEND_SAVE_STATE, +pcmcia_socket_dev_suspend() will simply do nothing due to its check. */ +return pcmcia_socket_dev_suspend (&dev->dev, state,SUSPEND_SAVE_STATE ); }
include/linux/reboot.h +1 -1
@@ -21,7 +21,7 @@* CAD_OFF Ctrl-Alt-Del sequence sends SIGINT to init task. * POWER_OFF Stop OS and remove all power from system, if possible. * RESTART2 Restart system using given command string. -* SW_SUSPEND Suspend system using Software Suspend if compiled in +* SW_SUSPEND Suspend system using software suspend if compiled in. */ #define LINUX_REBOOT_CMD_RESTART 0x01234567
include/linux/suspend.h +11 -7
@@ -55,10 +55,6 @@extern int register_suspend_notifier (struct notifier_block *);extern int unregister_suspend_notifier (struct notifier_block *); -extern void refrigerator (unsigned long ); - -extern int freeze_processes (void ); -extern void thaw_processes (void ); extern unsigned int nr_copy_pages __nosavedata; extern suspend_pagedir_t *pagedir_nosave __nosavedata;
@@ -76,15 +72,23 @@extern void do_suspend_lowlevel_s4bios (int resume);#else -static inline void software_suspend (void ) -{ -} +static inline void software_suspend (void ) { }#define software_resume () do { } while(0)#define register_suspend_notifier (a) do { } while(0)#define unregister_suspend_notifier (a) do { } while(0) +#endif + +#ifdef CONFIG_PM +extern void refrigerator (unsigned long ); +extern int freeze_processes (void ); +extern void thaw_processes (void ); +#else #define refrigerator (a) do { BUG(); } while(0)#define freeze_processes () do { panic("You need CONFIG_SOFTWARE_SUSPEND to do sleeps."); } while(0)#define thaw_processes () do { } while(0)#endif +extern int prepare_suspend_console (void ); +extern void restore_console (void ); +#endif /* _LINUX_SWSUSP_H */
kernel/Makefile +1 -1
@@ -17,7 +17,7 @@ obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o -obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o +obj-$(CONFIG_PM) += suspend.o obj-$(CONFIG_COMPAT) += compat.o ifneq ($(CONFIG_IA64),y)
kernel/suspend.c +74 -81
274 lines not on this page · raw message
arch/i386/kernel/acpi/wakeup.S +5 -0
@@ -43,6 +43,11 @@ testl $1, video_flags - wakeup_code jz 1f + /* It is miracle that this works: + * PCI may or may not be initialized at this point + * I'm told we should pass device ID to video bios + However it works on some real machines... + */ lcall $0xc000,$3 movw %cs, %ax movw %ax, %ds # Bios might have played with that
drivers/net/8139too.c +12 -1
@@ -109,6 +109,7 @@#include <linux/ethtool.h> #include <linux/mii.h> #include <linux/completion.h> +#include <linux/suspend.h> #include <linux/crc32.h> #include <asm/io.h> #include <asm/uaccess.h>
@@ -565,6 +566,7 @@void *mmio_addr;int drv_flags;struct pci_dev *pci_dev; +u32 pci_state[16 ];struct net_device_stats stats;unsigned char *rx_ring;unsigned int cur_rx;/* Index into the Rx buffer of next Rx pkt. */
@@ -1597,6 +1599,8 @@ timeout = next_tick;do { timeout =interruptible_sleep_on_timeout (&tp->thr_wait, timeout); +if (current->flags &PF_FREEZE ) +refrigerator (PF_IOTHREAD ); }while (!signal_pending (current) && (timeout >0 ));if (signal_pending (current)) {
@@ -2566,6 +2570,9 @@ tp->stats.rx_missed_errors +=RTL_R32 (RxMissed);RTL_W32 (RxMissed,0 ); +pci_save_state (pdev, tp->pci_state); +pci_set_power_state (pdev,3 ); +spin_unlock_irqrestore (&tp->lock, flags);return 0 ; }
@@ -2574,11 +2581,15 @@static int rtl8139_resume (struct pci_dev *pdev) {struct net_device *dev =pci_get_drvdata (pdev); +struct rtl8139_private *tp = dev->priv;if (!netif_running (dev))return 0 ; -netif_device_attach (dev); +pci_set_power_state (pdev,0 ); +pci_restore_state (pdev, tp->pci_state); +rtl8139_init_ring (dev);rtl8139_hw_start (dev); +netif_device_attach (dev);return 0 ; }
drivers/pci/pci-driver.c +3 -5
@@ -179,11 +179,9 @@struct pci_dev * pci_dev =to_pci_dev (dev);if (pci_dev->driver) { -/* We may not call PCI drivers resume at -RESUME_POWER_ON because interrupts are not yet -working at that point. Calling resume at -RESUME_RESTORE_STATE seems like solution. */ -if (level ==RESUME_RESTORE_STATE && pci_dev->driver->resume) +if (level ==RESUME_POWER_ON && pci_dev->driver->power_on) + pci_dev->driver->power_on (pci_dev); +else if (level ==RESUME_RESTORE_STATE && pci_dev->driver->resume) pci_dev->driver->resume (pci_dev); }return 0 ;
include/linux/pci.h +1 -0
@@ -512,6 +512,7 @@void (*remove) (struct pci_dev *dev);/* Device removed (NULL if not a hot-plug capable driver) */ int (*save_state) (struct pci_dev *dev,u32 state);/* Save Device Context */ int (*suspend) (struct pci_dev *dev,u32 state);/* Device suspended */ +int (*power_on) (struct pci_dev *dev);/* Device power on */ int (*resume) (struct pci_dev *dev);/* Device woken up */ int (*enable_wake) (struct pci_dev *dev,u32 state,int enable);/* Enable wake event */
%diffstat
arch/i386/kernel/Makefile | 3 arch/i386/kernel/acpi/wakeup.S | 5 + arch/i386/kernel/suspend_asm.S | 3 arch/i386/kernel/sysenter.c | 2 arch/x86_64/kernel/time.c | 25 +++++- drivers/acpi/Kconfig | 4 - drivers/acpi/sleep/main.c | 20 +++-- drivers/base/power.c | 6 - drivers/input/keyboard/atkbd.c | 11 +- drivers/input/power.c | 16 +++- drivers/input/serio/i8042.c | 5 - drivers/net/8139too.c | 13 +++ drivers/pci/pci-driver.c | 8 -- drivers/pcmcia/yenta_socket.c | 5 + include/linux/pci.h | 1 include/linux/reboot.h | 2 include/linux/serio.h | 4 - include/linux/suspend.h | 18 ++-- kernel/Makefile | 2 kernel/suspend.c | 155 +++++++++++++++++++---------------------- 20 files changed, 172 insertions(+), 136 deletions(-)
Signature · 2 lines
When do you have a heart between your knees? [Johanka's followup: and *two* hearts?]