^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * SA1100 Power Management Routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modify it under the terms of the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * History:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * 2001-02-06: Cliff Brake Initial code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Chester Kuo <chester@linux.org.tw>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Save more value for the resume function! Support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Bitsy/Assabet/Freebird board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * 2001-08-29: Nicolas Pitre <nico@fluxnic.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Cleaned up, pushed platform dependent stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * in the platform specific files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * Storage is local on the stack now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <mach/hardware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/memory.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/mach/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) extern int sa1100_finish_suspend(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * List of global SA11x0 peripheral registers to preserve.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * More ones like CP and general purpose register values are preserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * on the stack and then the stack pointer is stored last in sleep.S.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) SLEEP_SAVE_Ser1SDCR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) SLEEP_SAVE_COUNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static int sa11x0_pm_enter(suspend_state_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) gpio = GPLR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* save vital registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) SAVE(GPDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) SAVE(GAFR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) SAVE(PPDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) SAVE(PPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) SAVE(PPAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) SAVE(PSDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) SAVE(Ser1SDCR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Clear previous reset status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* set resume return address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) PSPR = __pa_symbol(cpu_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* go zzz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) cpu_suspend(0, sa1100_finish_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Ensure not to come back here if it wasn't intended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) RCSR = RCSR_SMR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) PSPR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * Ensure interrupt sources are disabled; we will re-init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * the interrupt subsystem via the device manager.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) ICLR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ICCR = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ICMR = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* restore registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) RESTORE(GPDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) RESTORE(GAFR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) RESTORE(PPDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) RESTORE(PPSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) RESTORE(PPAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) RESTORE(PSDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) RESTORE(Ser1SDCR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) GPSR = gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) GPCR = ~gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Clear the peripheral sleep-hold bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) PSSR = PSSR_PH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const struct platform_suspend_ops sa11x0_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) .enter = sa11x0_pm_enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) .valid = suspend_valid_only_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int __init sa11x0_pm_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) suspend_set_ops(&sa11x0_pm_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }