From: Leblanc f. <fle...@us...> - 2002-03-07 09:15:19
|
Update of /cvsroot/linux-mips/linux/arch/mips/vr41xx/common In directory usw-pr-cvs1:/tmp/cvs-serv3157/arch/mips/vr41xx/common Modified Files: Makefile Added Files: adif.c giuinfo.c gpiolcd.c led.c power.c Log Message: Adds more VR stuff for Cassiopeia E15 Support. --- NEW FILE: adif.c --- /* * linux/arch/mips/vr41xx/adif.c * * VR41xx Lvl A/D driver * * Parts Copyright (C) 2001 Chris AtLee <ca...@ca...> * Parts Copyright (C) 2001 Paul Jimenez <pj...@ag...> * Parts Copyright (C) 2001 Alexandre d'Alton <ale...@ya...> * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include <linux/module.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/fs.h> #include <linux/major.h> #include <linux/sched.h> #include <asm/uaccess.h> #include <asm/system.h> #include <asm/irq.h> #include <asm/vr41xx.h> #define VR41XX_ADIF_MINOR 15 static wait_queue_head_t wait; static void adif_irq_handler (int irq, void *dev_id, struct pt_regs *regs) { wake_up_interruptible (&wait); } static int adif_open (struct inode *inode, struct file *file) { /* Readonly, sure they can all be open */ return 0; } static int adif_close (struct inode *inode, struct file *file) { return 0; } static ssize_t adif_read (struct file *file, char *buf, size_t count, loff_t * offset) { int original_stable; unsigned short adin[4]; ssize_t retval; unsigned long flags; unsigned int j; if (count < 4 * sizeof (short)) { printk ("adif: Invalid count(%d) specified (must be at least %d)\n", count, 4 * sizeof (short)); return 0; } /*** get battery readings here */ /** wait til we get into one of Standby, WaitPenTouch, or Interval state per VR4181.pdf 19.4 */ /* If the pen is down, we can't use the PIU, so we wait. */ cli(); while(*VR41XX_PIUCNTREG & 0x2000){ sti(); j = jiffies + 100; while(jiffies < j) schedule(); } save_and_cli (flags); /* We need to activate the PIU clocks. */ *VR41XX_CMUCLKMSK |= (VR41XX_CMUCLKMSK_MSKKIU| VR41XX_CMUCLKMSK_MSKSIU); barrier (); /* All these step are probably not needed, but they were for debugging */ *VR41XX_PIUCNTREG = 1; *VR41XX_PIUCNTREG = 0x2; /* Power up the PIU */ #define PIU_IN_STANDBY ((*VR41XX_PIUCNTREG & 0x1c00) == 0x0400) while (!PIU_IN_STANDBY) *VR41XX_PIUCNTREG &= ~0x2; /* Go in standby state */ barrier (); *VR41XX_PIUAMSKREG = 0xFF0F; /* Mask ADIN[0-2] & MIC pins */ barrier (); restore_flags (flags); /* set irq */ /* When we share IRQ we have to differentiate between two handlers for the same IRQ, that's why we put the address ow the wait queue as last argument to request_irq. */ if (retval = request_irq (VR41XX_IRQ_PIU, adif_irq_handler, SA_SHIRQ, "vr41xx_battery_level", &wait)) { /* restore PIUSTBLREG */ // *VR41XX_PIUSTBLREG = original_stable; printk ("adif: unable to request_irq (%d)\n", retval); return -retval; } barrier (); save_and_cli (flags); /* start the process */ *VR41XX_PIUASCNREG = 0x1; barrier (); *VR41XX_PIUCNTREG |= 0x0004; barrier (); restore_flags (flags); /* sleep until the value is ready */ interruptible_sleep_on (&wait); save_and_cli (flags); *VR41XX_PIUAMSKREG = 0xFFF0; *VR41XX_PIUASCNREG = 0x2; barrier (); /* read values */ adin[0] = *VR41XX_PIUAB0REG; adin[1] = *VR41XX_PIUAB1REG; adin[2] = *VR41XX_PIUAB2REG; adin[3] = *VR41XX_PIUAB3REG; /* Reset the PIU Controler in its default state */ *VR41XX_PIUCNTREG = 1; barrier(); *VR41XX_PIUCNTREG = 0x2; /* Power up the PIU */ barrier(); while (!PIU_IN_STANDBY) *VR41XX_PIUCNTREG &= ~0x2; /* Go in standby state */ *VR41XX_PIUCNTREG = 0x0322; barrier (); *VR41XX_PIUSIVLREG = 333; // set interval to .01 sec default *VR41XX_PIUSTBLREG = 0x10; barrier (); *VR41XX_MPIUINTREG = 0x007d; barrier (); *VR41XX_PIUCNTREG = 0x0326; // resume autoscan barrier (); /* Shut down the clocks. */ *VR41XX_CMUCLKMSK &= ~(VR41XX_CMUCLKMSK_MSKKIU | VR41XX_CMUCLKMSK_MSKSIU); restore_flags (flags); free_irq (VR41XX_IRQ_PIU, &wait); // printk ("adif: returning %d, %d, %d, %d\n", adin[0], adin[1], adin[2], // adin[3]); if (!access_ok(VERIFY_WRITE, buf, 8)) return -EFAULT; __put_user (adin[0], (short *) (buf)); __put_user (adin[1], (short *) (buf + 2)); __put_user (adin[2], (short *) (buf + 4)); __put_user (adin[3], (short *) (buf + 6)); return 4 * sizeof (short); } static struct file_operations adif_fops; static struct miscdevice adif_device; static int adif_init (void) { int retval; init_waitqueue_head (&wait); /* NULL out the data structure before filling it */ memset (&adif_fops, 0, sizeof (struct file_operations)); adif_fops.read = adif_read; adif_fops.open = adif_open; adif_fops.release = adif_close; /* NULL out the data structure before filling it */ memset (&adif_device, 0, sizeof (struct miscdevice)); adif_device.minor = VR41XX_ADIF_MINOR; adif_device.name = "adif"; adif_device.fops = &adif_fops; /* register it */ retval = misc_register (&adif_device); if (retval < 0) { printk ("Failed to register A/D interface driver\n"); return retval; } printk ("A/D interface driver registered on %i,%i\n", MISC_MAJOR, VR41XX_ADIF_MINOR); return 0; } static void adif_exit (void) { if (0 > misc_deregister (&adif_device)) printk ("Error unregistering A/D interface driver\n"); } module_init (adif_init); module_exit (adif_exit); --- NEW FILE: giuinfo.c --- /* * linux/arch/mips/vr41xx/giuinfo.c * * Shows General Purpose I/O status in /proc/giuinfo * * Copyright (C) 1999 Bradley D. LaRonde * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * */ #include <linux/kernel.h> #include <linux/proc_fs.h> #include <linux/init.h> #include <asm/vr41xx.h> static int get_giuinfo(char *page, char **start, off_t off, int count, int *eof, void *data) { int len; // return the giu register info // buffer is PAGE_SIZE long, we're OK for all page sizes VR41xx supports #ifdef CONFIG_CPU_VR4181 len = sprintf(page, "GPMD0REG: 0x%04hx\n" "GPMD1REG: 0x%04hx\n" "GPMD2REG: 0x%04hx\n" "GPMD3REG: 0x%04hx\n" "GPDATHREG: 0x%04hx\n" "GPDATLREG: 0x%04hx\n" "GPINTEN: 0x%04hx\n" "GPINTMSK: 0x%04hx\n" "GPINTTYPH: 0x%04hx\n" "GPINTTYPL: 0x%04hx\n" "GPINTSTAT: 0x%04hx\n" "GPHIBSTH: 0x%04hx\n" "GPHIBSTL: 0x%04hx\n" "GPSICTL: 0x%04hx\n" "KEYEN: 0x%04hx\n" "PCS0STRA: 0x%04hx\n" "PCS0STPA: 0x%04hx\n" "PCS0HIA: 0x%04hx\n" "PCS1STRA: 0x%04hx\n" "PCS1STPA: 0x%04hx\n" "PCS1HIA: 0x%04hx\n" "PCSMODE: 0x%04hx\n" "LCDGPMODE: 0x%04hx\n" "MISCREG0: 0x%04hx\n" "MISCREG1: 0x%04hx\n" "MISCREG2: 0x%04hx\n" "MISCREG3: 0x%04hx\n" "MISCREG4: 0x%04hx\n" "MISCREG5: 0x%04hx\n" "MISCREG6: 0x%04hx\n" "MISCREG7: 0x%04hx\n" "MISCREG8: 0x%04hx\n" "MISCREG9: 0x%04hx\n" "MISCREG10: 0x%04hx\n" "MISCREG11: 0x%04hx\n" "MISCREG12: 0x%04hx\n" "MISCREG13: 0x%04hx\n" "MISCREG14: 0x%04hx\n" "MISCREG15: 0x%04hx\n", *VR41XX_GPMD0REG, *VR41XX_GPMD1REG, *VR41XX_GPMD2REG, *VR41XX_GPMD3REG, *VR41XX_GPDATHREG, *VR41XX_GPDATLREG, *VR41XX_GPINTEN, *VR41XX_GPINTMSK, *VR41XX_GPINTTYPH, *VR41XX_GPINTTYPL, *VR41XX_GPINTSTAT, *VR41XX_GPHIBSTH, *VR41XX_GPHIBSTL, *VR41XX_GPSICTL, *VR41XX_KEYEN, *VR41XX_PCS0STRA, *VR41XX_PCS0STPA, *VR41XX_PCS0HIA, *VR41XX_PCS1STRA, *VR41XX_PCS1STPA, *VR41XX_PCS1HIA, *VR41XX_PCSMODE, *VR41XX_LCDGPMODE, *VR41XX_MISCREG0, *VR41XX_MISCREG1, *VR41XX_MISCREG2, *VR41XX_MISCREG3, *VR41XX_MISCREG4, *VR41XX_MISCREG5, *VR41XX_MISCREG6, *VR41XX_MISCREG7, *VR41XX_MISCREG8, *VR41XX_MISCREG9, *VR41XX_MISCREG10, *VR41XX_MISCREG11, *VR41XX_MISCREG12, *VR41XX_MISCREG13, *VR41XX_MISCREG14, *VR41XX_MISCREG15); #else len = sprintf(page, "giuiosell: 0x%04hx\n" "giuioselh: 0x%04hx\n" "giupiodl: 0x%04hx\n" "giupiodh: 0x%04hx\n" "giupodatl: 0x%04hx\n", *VR41XX_GIUIOSELL, *VR41XX_GIUIOSELH, *VR41XX_GIUPIODL, *VR41XX_GIUPIODH, *VR41XX_GIUPODATL); #endif if (len <= off+count) *eof = 1; *start = page + off; len -= off; if (len > count) len = count; if (len < 0) len = 0; return len; } static int __init giuinfo_init(void) { create_proc_read_entry("giuinfo", 0, NULL, get_giuinfo, NULL); return 0; } __initcall(giuinfo_init); --- NEW FILE: gpiolcd.c --- /* * linux/arch/mips/vr41xx/gpiolcd.c * * Platform support for the machine which LCD control by GPIO. * * Copyright (C) 2000 SATO Kazumi * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * */ #include <asm/io.h> #include <asm/system.h> #include <asm/vr41xx.h> #ifdef CONFIG_NEC_MOBILEGEAR2_R300 #define LCDON VR41XX_GIUPIODL_GPIO10 /* GPIO[10] 0100 0000 0000 */ #define LCDON_PORT VR41XX_GIUPIODL #define LIGHTON VR41XX_GIUPODATL_GPIO45 /* GPIO[45] 10 0000 0000 0000 */ #define LIGHTON_PORT VR41XX_GIUPODATL #define MAXCONTRAST 6 /* XXX temporary */ #elif defined(CONFIG_NEC_MOBILEGEAR2_R310) #define LCDON VR41XX_GIUPIODL_GPIO10 /* GPIO[10] 0100 0000 0000 */ #define LCDON_PORT VR41XX_GIUPIODL #define LIGHTON VR41XX_GIUPODATL_GPIO45 /* GPIO[45] 10 0000 0000 0000 */ #define LIGHTON_PORT VR41XX_GIUPODATL #define MAXCONTRAST 6 /* XXX temporary */ #elif defined(CONFIG_CASIO_E15) #define LCDON VR41XX_GIUPIODH_GPIO24 /* GPIO[24] 0000 0001 0000 0000 */ #define LCDON_PORT VR41XX_GIUPIODH #define LIGHTON VR41XX_GIUPIODH_GPIO26 /* GPIO[26] 0000 0100 0000 0000 */ #define LIGHTON_PORT VR41XX_GIUPIODH #define MAXCONTRAST 6 /* XXX temporary */ #else #error no LCD GPIO Infomation.... #endif static int backlight, contrast, lcdpower; void gpiolcd_init_backlight(void) { #ifdef STANDALONE backlight = 1; #else /* STANDALONE */ /* save boot time status (maybe set by Windows CE) */ if (*LIGHTON_PORT&LIGHTON) backlight = 1; else backlight = 0; #endif /* STANDALONE */ } int get_gpiolcd_backlight(void) { return backlight; } int gpiolcd_backlight(int n) { int flags; if(n == 0) { backlight = 0; save_and_cli(flags); *LIGHTON_PORT &= ~LIGHTON; restore_flags(flags); // Turn the backlight off. } else { backlight = 1; save_and_cli(flags); *LIGHTON_PORT |= LIGHTON; restore_flags(flags); } return 0; } void gpiolcd_init_contrast(void) { #ifdef STANDALONE contrast = MAXCONTRAST; #else /* STANDALONE */ /* save boot time status (maybe set by Windows CE) */ /* but we don't know current value methods, so set constant */ contrast = MAXCONTRAST; #endif /* STANDALONE */ } int get_gpiolcd_contrast(void) { return contrast; } int gpiolcd_contrast(int n) { if (n > MAXCONTRAST) contrast = MAXCONTRAST; else contrast = n; // Turn the lcd on and some contrast. return 0; } int get_gpiolcd_lcdpower(void) { return lcdpower; } int gpiolcd_lcdpower(int n) { int flags; lcdpower = n; if(n == 0) { save_and_cli(flags); *LCDON_PORT &= ~LCDON; restore_flags(flags); } else { save_and_cli(flags); *LCDON_PORT |= LCDON; restore_flags(flags); } return 0; } void gpiolcd_setup(void) { lcdpower = 1; /* boot time always on */ /* backlight & contrast inherit by WinCE */ gpiolcd_init_backlight(); gpiolcd_init_contrast(); gpiolcd_lcdpower(lcdpower); gpiolcd_contrast(contrast); gpiolcd_backlight(backlight); } --- NEW FILE: led.c --- /* * linux/arch/mips/vr41xx/led.c * * VR41xx LED control unit (LCU) driver * * Copyright (C) 1999 Hiroshi Kawashima (kaw...@in...) * Copyright (C) 2001 François Leblanc <fra...@ce...> * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include <linux/kernel.h> #include <asm/vr41xx.h> void vr41xx_xblink_led(unsigned int times, unsigned int time_on, unsigned int time_off) { time_on &= 0x007f; // only lower 7 bit is used if (time_on == 0) return; // Illegal value time_off &= 0x007f; // only lower 7 bit is used if (time_off == 0) return; // Illegal value if (*VR41XX_LEDCNTREG & 0x0001) return; // Now blinking, so ignore this request *VR41XX_LEDHTSREG = time_on; // LED on time (1 = 0.0625 sec) *VR41XX_LEDLTSREG = time_off; // LED off time (1 = 0.0625 sec) *VR41XX_LEDASTCREG = times; // How many times blink *VR41XX_LEDCNTREG = 0x0002; // Enable auto stop *VR41XX_LEDCNTREG |= 0x0001; // Start blinking // Wait for LEDINT while ((*VR41XX_LEDINTREG & 0x0001) == 0) ; // Clear LEDINT *VR41XX_LEDINTREG = 0x0001; } void vr41xx_blink_led(unsigned int times, unsigned int length) { /* keep compatible */ vr41xx_xblink_led(times, length, 1); } --- NEW FILE: power.c --- /* * VR41xx reset and power management interface * PM User interface loosely based on Andrew Henroid's i386 ACPI driver * * Copyright (C) 2000 Michael Klar * Copyright (C) 2002 François Leblanc <fra...@ce...> * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * */ #include <linux/kernel.h> #include <linux/init.h> #include <linux/config.h> #include <linux/delay.h> #include <linux/mm.h> #include <linux/sysctl.h> #include <linux/pm.h> #include <linux/acpi.h> #include <linux/irq.h> /* for disable_irq, enable_irq, to be removed */ #include <linux/reboot.h> #include <asm/vr41xx.h> #include <asm/cacheops.h> #include <asm/mipsregs.h> #include <asm/pgalloc.h> #include <asm/power.h> /* * vr41xx_dma_sem is needed because we cannot suspend while a DMA transfer * is in progress, otherwise the CPU will be left in an undefined state. */ extern struct semaphore vr41xx_dma_sem; #ifdef CONFIG_PM_SUSPEND_WAKEUP // // On VR41xx CPUs, the hibernate instruction will cut power to most of // the device. On a wakeup event (usually power button), the CPU // restarts at the reset vector in ROM, so the bootloader has to run // again in order to pass control back to the kernel. As a result, // the bootloader (and/or some level of code in the ROM) must not // disturb the contents of RAM before passing control to the kernel // when waking from hibernate. // // This code uses the power management kernel interface to the // peripheral drivers. It is not real ACPI support, which would require // some rather impractical (for this class of devices) hardware and // firmware extensions. Also, for now, the SUSPEND and RESUME functions // in the peripheral drivers just need to do any necessary hardware // state saving and restoring. Power, IRQ mask, clock mask, and GPIO // state are handled globally. This will probably change in the future // to allow for power-state control of individual peripheral units. // // Right now, the data arg passed to the pm_request callback for SUSPEND // and RESUME means: // 0: restore state and return to powered-on // 1: save state and prepare for hibernate, no need to power off because // power will be removed globally // 2: save state and prepare for suspend, global power will remain, so // the peripheral driver may want to power down its local power // 3: prepare for suspend, peripherals should appear to user to be // running, most interrupts can wake from this state // The numbers above should get replaced with an enum evetually, and // the requirements for each mode will probably change, since the above // doesn't really make sense (eg, no need to save state for 2, except // that we need something to restore to for 0). The pm_request callbacks // currently ignore the data value anyway.... // // This may seem like a bad idea to put the state information into the // data segment where the bootloader may overwrite it, but if the // bootloader rewrites data (and/or bss), it won't support wake from // hibernate, anyway. // unsigned int powerevent_queued; unsigned int hibernation_state = LOAD_MAGIC; static unsigned short clkmsk_state; //extern void do_pm_irq_request(pm_request_t rqst); #ifndef VR41XX_IRQ_MAX #define VR41XX_IRQ_MAX ((VR41XX_NUM_CPU_IRQ)+(VR41XX_NUM_SYS_IRQ)+(VR41XX_NUM_GPIO_IRQ)) #endif // // // Unlike the real pm_request callbacks, this one doesn't get registered // with PM, and only gets called from do_hibernate and do_wakeup, because // it has to happen in a certain order. It also assumes ints disabled. // static void do_pm_irq_request(pm_request_t rqst) { static unsigned short irq_mask[(VR41XX_IRQ_MAX + 9)/16]; unsigned int status; switch (rqst) { case PM_RESUME: status = read_32bit_cp0_register(CP0_STATUS) & 0xffff00ff; write_32bit_cp0_register(CP0_STATUS, status | irq_mask[0]); *VR41XX_MSYSINT1REG = irq_mask[1]; *VR41XX_MSYSINT2REG = irq_mask[2]; #ifdef CONFIG_CPU_VR4181 *VR41XX_GPINTMSK = irq_mask[3]; #else *VR41XX_MGIUINTLREG = irq_mask[3]; *VR41XX_MGIUINTHREG = irq_mask[4]; #endif break; case PM_SUSPEND: irq_mask[0] = read_32bit_cp0_register(CP0_STATUS) & 0xff00; irq_mask[1] = *VR41XX_MSYSINT1REG; irq_mask[2] = *VR41XX_MSYSINT2REG; #ifdef CONFIG_CPU_VR4181 irq_mask[3] = *VR41XX_GPINTMSK; #else irq_mask[3] = *VR41XX_MGIUINTLREG; irq_mask[4] = *VR41XX_MGIUINTHREG; #endif break; } } #ifdef CONFIG_CPU_VR4181 #define MIN_GPIOREG VR41XX_GPMD0REG #define MAX_GPIOREG VR41XX_LCDGPMODE #else #define MIN_GPIOREG VR41XX_GIUIOSELL #define MAX_GPIOREG VR41XX_GIUINTHTSELH #endif #define NR_GPIOREGS (((long)MAX_GPIOREG - (long)MIN_GPIOREG) / sizeof(short) + 1) unsigned short gpio_state[NR_GPIOREGS]; asmlinkage void do_hibernate(void *sp) { int i; cli(); powerevent_queued = 0; if (pm_send_all(PM_SUSPEND, (void *)1)) { sti(); up(&vr41xx_dma_sem); return; } do_pm_irq_request(PM_SUSPEND); for (i = 0; i < NR_GPIOREGS; i++) gpio_state[i] = *(MIN_GPIOREG + i); clkmsk_state = *VR41XX_CMUCLKMSK; // we may want to put in some checksum or CRC on all of RAM, too hibernation_state = HIB_MAGIC; //flush_cache_all(); //vr41xx_hibernate(); machine_halt (); // never reached... } //asmlinkage int do_wakeup(void) asmlinkage void do_wakeup(char *command) { int i, retval; // start out with something reasonable in CP0_STATUS, this will get // replaced when context is restored. ints disbaled at this point write_32bit_cp0_register(CP0_STATUS, ST0_CU0); // Do what loadmmu would have done if cold init //set_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); change_cp0_config(CONF_CM_CMASK, CONF_CM_CACHABLE_NONCOHERENT); flush_cache_all(); write_32bit_cp0_register(CP0_WIRED, 0); set_pagemask(PM_4K); //write_32bit_cp0_register(CP0_PAGEMASK, PM_4K); flush_tlb_all(); // this is about the point where we would check CRC if we did one *VR41XX_CMUCLKMSK = clkmsk_state; for (i = 0; i < NR_GPIOREGS; i++) *(MIN_GPIOREG + i) = gpio_state[i]; do_pm_irq_request(PM_RESUME); retval = pm_send_all(PM_RESUME, (void *)0); if (!retval) { sti(); up(&vr41xx_dma_sem); } //return retval; } /* * Enter system sleep state (hibernate, really soft-off) * * Actually, all this does is to set a flag, so the tail end of the syscall * handler jumps to do_hibernate above, rather than executing * o32_ret_from_sys_call. That just makes for a convenient place to restore * context from, since context is already saved on the stack at that point, * and bottom-half processing already done. The wakeup part is done in * kernel_entry, since waking up from hibernate will restart at reset vector. */ static int pm_do_sleep(ctl_table *ctl, int write, struct file *file, void *buffer, size_t *len) { if (!write) { if (file->f_pos) { *len = 0; return 0; } } else { if (file->f_flags & O_NONBLOCK) { if (down_trylock(&vr41xx_dma_sem)) return -EAGAIN; } else { if (down_interruptible(&vr41xx_dma_sem)) return -ERESTARTSYS; } powerevent_queued = 1; } file->f_pos += *len; return 0; } #endif // CONFIG_PM_SUSPEND_WAKEUP #ifdef CONFIG_PM_POWERED_SUSPEND /* * Enter system "suspend" state, CPU remains powered but most/all clocks off */ static int pm_do_suspend(ctl_table *ctl, int write, struct file *file, void *buffer, size_t *len) { if (!write) { if (file->f_pos) { *len = 0; return 0; } } else { int retval; // Must not suspend while DMA in progress if (file->f_flags & O_NONBLOCK) { if (down_trylock(&vr41xx_dma_sem)) return -EAGAIN; } else { if (down_interruptible(&vr41xx_dma_sem)) return -ERESTARTSYS; } retval = pm_send_all(PM_SUSPEND, (void *)2); if (retval) { up(&vr41xx_dma_sem); return retval; } //vr41xx_suspend(); machine_power_off (); retval = pm_send_all(PM_RESUME, (void *)0); up(&vr41xx_dma_sem); if (retval) return retval; } file->f_pos += *len; return 0; } #endif // CONFIG_PM_POWERED_SUSPEND #ifdef CONFIG_PM_STANDBY /* * Enter system "standby" state, CPU remains powered, clocks on */ static int pm_do_standby(ctl_table *ctl, int write, struct file *file, void *buffer, size_t *len) { if (!write) { if (file->f_pos) { *len = 0; return 0; } } else { // MFK: replace with send PM_SUSPEND request to pm_time_request: disable_irq(VR41XX_IRQ_INT1); //vr41xx_standby(); machine_power_off (); // MFK: replace with send PM_RESUME request to pm_time_request: enable_irq(VR41XX_IRQ_INT1); } file->f_pos += *len; return 0; } #endif // CONFIG_PM_STANDBY /* * NOTE1: We're hijacking the ACPI binary ctl_name's for now. Don't expect * this to necessarily behave as ACPI does, some are blatently wrong. * NOTE2: Don't get used to the text names, either, they are subject to change * if we ever come up with a real naming convention.... * NOTE3: For that matter, don't get used to this being done via sysctl, * that's subject to change, too. */ static struct ctl_table pm_table[] = { #ifdef CONFIG_PM_SUSPEND_WAKEUP {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &pm_do_sleep}, #endif #ifdef CONFIG_PM_POWERED_SUSPEND {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, &pm_do_suspend}, #endif #ifdef CONFIG_PM_STANDBY {ACPI_S0_SLP_TYP, "standby", NULL, 0, 0600, NULL, &pm_do_standby}, #endif {0} }; static struct ctl_table pm_dir_table[] = { {CTL_ACPI, "pm", NULL, 0, 0555, pm_table}, {0} }; /* * Initialize the power management user interface */ static int __init pm_init(void) { register_sysctl_table(pm_dir_table, 1); return 0; } __initcall(pm_init); Index: Makefile =================================================================== RCS file: /cvsroot/linux-mips/linux/arch/mips/vr41xx/common/Makefile,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- Makefile 7 Mar 2002 03:16:53 -0000 1.5 +++ Makefile 7 Mar 2002 09:15:16 -0000 1.6 @@ -19,4 +19,12 @@ obj-$(CONFIG_VR41XX_TIME_C) += time.o +obj-$(CONFIG_ADIF) += adif.o +obj-$(CONFIG_VR41XX_LED) += led.o +obj-$(CONFIG_PROC_GIUINFO) += giuinfo.o +obj-$(CONFIG_PM) += power.o +obj-$(CONFIG_GPIO_LCD) += gpiolcd.o + +#obj-$(CONFIG_BLK_DEV_IDE) += ide-vr41xx.o + include $(TOPDIR)/Rules.make |