Merge branch 'core/topology' of git://git.kernel.org/pub/scm/linux/kernel/git/tip...
[linux-2.6] / arch / arm / mach-s3c2412 / sleep.S
1 /* linux/arch/arm/mach-s3c2412/sleep.S
2  *
3  * Copyright (c) 2007 Simtec Electronics
4  *      Ben Dooks <ben@simtec.co.uk>
5  *
6  * S3C2412 Power Manager low-level sleep support
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22
23 #include <linux/linkage.h>
24 #include <asm/assembler.h>
25 #include <asm/hardware.h>
26 #include <asm/arch/map.h>
27
28 #include <asm/arch/regs-irq.h>
29
30         .text
31
32         .global s3c2412_sleep_enter
33
34 s3c2412_sleep_enter:
35         mov     r0, #0                  /* argument for coprocessors */
36         ldr     r1, =S3C2410_INTPND
37         ldr     r2, =S3C2410_SRCPND
38         ldr     r3, =S3C2410_EINTPEND
39
40         teq     r0, r0
41         bl      s3c2412_sleep_enter1
42         teq     pc, r0
43         bl      s3c2412_sleep_enter1
44
45         .align  5
46
47         /* this is called twice, first with the Z flag to ensure that the
48          * instructions have been loaded into the cache, and the second
49          * time to try and suspend the system.
50         */
51 s3c2412_sleep_enter1:
52         mcr     p15, 0, r0, c7, c10, 4
53         mcrne   p15, 0, r0, c7, c0, 4
54
55         /* if we return from here, it is because an interrupt was
56          * active when we tried to shutdown. Try and ack the IRQ and
57          * retry, as simply returning causes the system to lock.
58         */
59
60         ldrne   r9, [ r1 ]
61         strne   r9, [ r1 ]
62         ldrne   r9, [ r2 ]
63         strne   r9, [ r2 ]
64         ldrne   r9, [ r3 ]
65         strne   r9, [ r3 ]
66         bne     s3c2412_sleep_enter1
67
68         mov     pc, r14