diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-22 11:22:59 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-22 11:22:59 -0700 |
commit | 7578634990fb47cc30083fbd812689aa6deacfc0 (patch) | |
tree | f493860658579d9572a19b3a41fcea2de035e49f /arch/arm/mach-pxa/pxa25x.c | |
parent | d7f5e3df3574c6e38b99f5fe22f15540b2b9811d (diff) | |
parent | 5957a4eb284dd6f522b248b674792416466555b2 (diff) |
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm: (60 commits)
[ARM] 4524/1: S3C: Move register out of include/asm-arm/arch-s3c2410
[ARM] 4523/1: S3C: Remove FIFO_MAX from uncompression headers
[ARM] 4522/1: S3C: split include/asm-arm/arch/memory.h
[ARM] 4521/2: S3C: Reorganise VA mapping headers
[ARM] 4520/1: S3C: Remove old VA values from static map
[ARM] 4519/1: S3C: split S3C2400 values out of S3C24XX map.h
[ARM] 4518/1: S3C: Rename watchdog configuration options
[ARM] 4517/1: S3C: Fix debug macros for ARM926 output
[ARM] 4516/1: S3C: Fix uncompressor serial output for ARM926
[ARM] 4515/1: S3C: Move uncompress code to plat-s3c
[ARM] 4514/1: S3C: Rename DEBUG_S3C2410_PORT and DEBUG_S3C_UART
[ARM] 4513/1: S3C: Rename CONFIG_S3C2410_LOWLEVEL_UART_PORT
[ARM] 4512/1: S3C: rename the debug macros for per-cpu updates
[ARM] 4511/1: S3C: updated LLSERIAL Kconfig defines for CPU support
[ARM] 4510/1: S3C: split debug-macro support into plat-s3c
[ARM] 4509/1: S3C: Create initial arch/arm/plat-s3c
[ARM] 4508/1: S3C: Move items to include/asm-arm/plat-s3c
[ARM] 4461/1: MXC platform and i.MX31ADS core support
[ARM] 4507/1: pxa2xx clock_event_device
[ARM] 4497/1: Only allow safe cache configurations on ARMv6 and later
...
Diffstat (limited to 'arch/arm/mach-pxa/pxa25x.c')
-rw-r--r-- | arch/arm/mach-pxa/pxa25x.c | 109 |
1 files changed, 91 insertions, 18 deletions
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index f36ca448338..6dfcca72e90 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -110,26 +110,99 @@ EXPORT_SYMBOL(get_lcdclk_frequency_10khz); #ifdef CONFIG_PM -void pxa_cpu_pm_enter(suspend_state_t state) +#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x +#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] + +#define RESTORE_GPLEVEL(n) do { \ + GPSR##n = sleep_save[SLEEP_SAVE_GPLR##n]; \ + GPCR##n = ~sleep_save[SLEEP_SAVE_GPLR##n]; \ +} while (0) + +/* + * List of global PXA peripheral registers to preserve. + * More ones like CP and general purpose register values are preserved + * with the stack pointer in sleep.S. + */ +enum { SLEEP_SAVE_START = 0, + + SLEEP_SAVE_GPLR0, SLEEP_SAVE_GPLR1, SLEEP_SAVE_GPLR2, + SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2, + SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2, + SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2, + SLEEP_SAVE_PGSR0, SLEEP_SAVE_PGSR1, SLEEP_SAVE_PGSR2, + + SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR0_U, + SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR1_U, + SLEEP_SAVE_GAFR2_L, SLEEP_SAVE_GAFR2_U, + + SLEEP_SAVE_PSTR, + + SLEEP_SAVE_ICMR, + SLEEP_SAVE_CKEN, + + SLEEP_SAVE_SIZE +}; + + +static void pxa25x_cpu_pm_save(unsigned long *sleep_save) +{ + SAVE(GPLR0); SAVE(GPLR1); SAVE(GPLR2); + SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2); + SAVE(GRER0); SAVE(GRER1); SAVE(GRER2); + SAVE(GFER0); SAVE(GFER1); SAVE(GFER2); + SAVE(PGSR0); SAVE(PGSR1); SAVE(PGSR2); + + SAVE(GAFR0_L); SAVE(GAFR0_U); + SAVE(GAFR1_L); SAVE(GAFR1_U); + SAVE(GAFR2_L); SAVE(GAFR2_U); + + SAVE(ICMR); + SAVE(CKEN); + SAVE(PSTR); +} + +static void pxa25x_cpu_pm_restore(unsigned long *sleep_save) { - extern void pxa_cpu_suspend(unsigned int); - extern void pxa_cpu_resume(void); + /* restore registers */ + RESTORE_GPLEVEL(0); RESTORE_GPLEVEL(1); RESTORE_GPLEVEL(2); + RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2); + RESTORE(GAFR0_L); RESTORE(GAFR0_U); + RESTORE(GAFR1_L); RESTORE(GAFR1_U); + RESTORE(GAFR2_L); RESTORE(GAFR2_U); + RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2); + RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2); + RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); + + RESTORE(CKEN); + RESTORE(ICMR); + RESTORE(PSTR); +} +static void pxa25x_cpu_pm_enter(suspend_state_t state) +{ CKEN = 0; switch (state) { case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); - pxa_cpu_suspend(PWRMODE_SLEEP); + pxa25x_cpu_suspend(PWRMODE_SLEEP); break; } } -static struct pm_ops pxa25x_pm_ops = { - .enter = pxa_pm_enter, +static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { + .save_size = SLEEP_SAVE_SIZE, .valid = pm_valid_only_mem, + .save = pxa25x_cpu_pm_save, + .restore = pxa25x_cpu_pm_restore, + .enter = pxa25x_cpu_pm_enter, }; + +static void __init pxa25x_init_pm(void) +{ + pxa_cpu_pm_fns = &pxa25x_cpu_pm_fns; +} #endif void __init pxa25x_init_irq(void) @@ -139,16 +212,16 @@ void __init pxa25x_init_irq(void) } static struct platform_device *pxa25x_devices[] __initdata = { - &pxamci_device, - &pxaudc_device, - &pxafb_device, - &ffuart_device, - &btuart_device, - &stuart_device, - &pxai2c_device, - &pxai2s_device, - &pxaficp_device, - &pxartc_device, + &pxa_device_mci, + &pxa_device_udc, + &pxa_device_fb, + &pxa_device_ffuart, + &pxa_device_btuart, + &pxa_device_stuart, + &pxa_device_i2c, + &pxa_device_i2s, + &pxa_device_ficp, + &pxa_device_rtc, }; static int __init pxa25x_init(void) @@ -159,14 +232,14 @@ static int __init pxa25x_init(void) if ((ret = pxa_init_dma(16))) return ret; #ifdef CONFIG_PM - pm_set_ops(&pxa25x_pm_ops); + pxa25x_init_pm(); #endif ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); } /* Only add HWUART for PXA255/26x; PXA210/250/27x do not have it. */ if (cpu_is_pxa25x()) - ret = platform_device_register(&hwuart_device); + ret = platform_device_register(&pxa_device_hwuart); return ret; } |