From: Leblanc f. <fle...@us...> - 2002-06-13 07:45:23
|
Update of /cvsroot/linux-mips/linux/arch/mips/vr41xx/vr4111/common In directory usw-pr-cvs1:/tmp/cvs-serv8622/arch/mips/vr41xx/vr4111/common Modified Files: time.c Log Message: *Casio cassiopeia E15 halt/restart full support throw win ce. *Gpio mapping update. Index: time.c =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/vr41xx/vr4111/common/time.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- time.c 10 Mar 2002 23:15:47 -0000 1.1 +++ time.c 13 Jun 2002 07:45:19 -0000 1.2 @@ -29,9 +29,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* + * Changes: + * Francois Leblanc <fra...@ce...> Thu, 11 Jun 2002 + * - Add power management, re-init real time and restart main timer. + */ #include <linux/spinlock.h> #include <linux/config.h> +#include <linux/init.h> #include <linux/irq.h> +#include <linux/pm.h> #include <asm/io.h> #include <asm/time.h> #include <asm/vr41xx.h> @@ -121,3 +128,55 @@ count + (mips_counter_frequency / HZ)); setup_irq(VR41XX_IRQ_TIMER, irq); } + +#ifdef CONFIG_PM +extern rwlock_t xtime_lock; + +static int pm_time_request(struct pm_dev *dev, pm_request_t rqst, void *data) +{ + unsigned long flags; + unsigned int count; + + if((board_time_init != vr4111_time_init) || + (board_timer_setup != vr4111_timer_setup)) + return 0; + + switch (rqst) { + case PM_SUSPEND: + disable_irq(VR41XX_IRQ_TIMER); + break; + case PM_RESUME: + write_lock_irqsave(&xtime_lock, flags); + enable_irq(VR41XX_IRQ_TIMER); + /* + * While power suspend interrupt may be disable but timer continue + * to count, so match time may be passed and timer interrupt pending + * but after hibernate command pending interrupts are clean (in hibernate + * mode cpu is in so deep sleep state that no interrupts can append) + * If restart without setting timer count again, kernel freeze until + * timer loop (from 0 second to fewer minut) very annoying. Avoid this + * by setting here next timer match count. + * - no harm if the machine is using another timer interrupt source. + * Note that writing to COMPARE register clears the interrupt + */ + count = read_32bit_cp0_register(CP0_COUNT); + write_32bit_cp0_register (CP0_COMPARE, + count + (mips_counter_frequency / HZ)); + xtime.tv_sec = rtc_get_time(); + xtime.tv_usec = 0; + write_unlock_irqrestore(&xtime_lock, flags); + break; + } + return 0; +} + +static int __init pm_time_init(void) +{ + pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, pm_time_request); + return 0; +} + +__initcall(pm_time_init); +#endif + + |