Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * PXA250/210 Power Management Routines
  3  *
  4  * Original code for the SA11x0:
  5  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
  6  *
  7  * Modified for the PXA250 by Nicolas Pitre:
  8  * Copyright (c) 2002 Monta Vista Software, Inc.
  9  *
 10  * This program is free software; you can redistribute it and/or
 11  * modify it under the terms of the GNU General Public License.
 12  */
 13 #include <linux/init.h>
 14 #include <linux/module.h>
 15 #include <linux/suspend.h>
 16 #include <linux/errno.h>
 17 #include <linux/time.h>
 18 
 19 #include <asm/hardware.h>
 20 #include <asm/memory.h>
 21 #include <asm/system.h>
 22 #include <asm/arch/pm.h>
 23 #include <asm/arch/pxa-regs.h>
 24 #include <asm/arch/lubbock.h>
 25 #include <asm/mach/time.h>
 26 
 27 struct pxa_cpu_pm_fns *pxa_cpu_pm_fns;
 28 static unsigned long *sleep_save;
 29 
 30 int pxa_pm_enter(suspend_state_t state)
 31 {
 32         unsigned long sleep_save_checksum = 0, checksum = 0;
 33         int i;
 34 
 35 #ifdef CONFIG_IWMMXT
 36         /* force any iWMMXt context to ram **/
 37         if (elf_hwcap & HWCAP_IWMMXT)
 38                 iwmmxt_task_disable(NULL);
 39 #endif
 40 
 41         /* skip registers saving for standby */
 42         if (state != PM_SUSPEND_STANDBY) {
 43                 pxa_cpu_pm_fns->save(sleep_save);
 44                 /* before sleeping, calculate and save a checksum */
 45                 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
 46                         sleep_save_checksum += sleep_save[i];
 47         }
 48 
 49         /* Clear sleep reset status */
 50         RCSR = RCSR_SMR;
 51 
 52         /* *** go zzz *** */
 53         pxa_cpu_pm_fns->enter(state);
 54         cpu_init();
 55 
 56         if (state != PM_SUSPEND_STANDBY) {
 57                 /* after sleeping, validate the checksum */
 58                 for (i = 0; i < pxa_cpu_pm_fns->save_size - 1; i++)
 59                         checksum += sleep_save[i];
 60 
 61                 /* if invalid, display message and wait for a hardware reset */
 62                 if (checksum != sleep_save_checksum) {
 63 #ifdef CONFIG_ARCH_LUBBOCK
 64                         LUB_HEXLED = 0xbadbadc5;
 65 #endif
 66                         while (1)
 67                                 pxa_cpu_pm_fns->enter(state);
 68                 }
 69                 pxa_cpu_pm_fns->restore(sleep_save);
 70         }
 71 
 72         pr_debug("*** made it back from resume\n");
 73 
 74         return 0;
 75 }
 76 
 77 EXPORT_SYMBOL_GPL(pxa_pm_enter);
 78 
 79 unsigned long sleep_phys_sp(void *sp)
 80 {
 81         return virt_to_phys(sp);
 82 }
 83 
 84 static int pxa_pm_valid(suspend_state_t state)
 85 {
 86         if (pxa_cpu_pm_fns)
 87                 return pxa_cpu_pm_fns->valid(state);
 88 
 89         return -EINVAL;
 90 }
 91 
 92 static struct platform_suspend_ops pxa_pm_ops = {
 93         .valid          = pxa_pm_valid,
 94         .enter          = pxa_pm_enter,
 95 };
 96 
 97 static int __init pxa_pm_init(void)
 98 {
 99         if (!pxa_cpu_pm_fns) {
100                 printk(KERN_ERR "no valid pxa_cpu_pm_fns defined\n");
101                 return -EINVAL;
102         }
103 
104         sleep_save = kmalloc(pxa_cpu_pm_fns->save_size, GFP_KERNEL);
105         if (!sleep_save) {
106                 printk(KERN_ERR "failed to alloc memory for pm save\n");
107                 return -ENOMEM;
108         }
109 
110         suspend_set_ops(&pxa_pm_ops);
111         return 0;
112 }
113 
114 device_initcall(pxa_pm_init);
115 
  This page was automatically generated by the LXR engine.