1/* SPDX-License-Identifier: GPL-2.0+ */
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
9#include <linux/linkage.h>
10#include <asm/assembler.h>
11#include <mach/hardware.h>
12#include <mach/map.h>
13
14#include <mach/regs-irq.h>
15
16	.text
17
18	.global	s3c2412_sleep_enter
19
20s3c2412_sleep_enter:
21	mov	r0, #0			/* argument for coprocessors */
22	ldr	r1, =S3C2410_INTPND
23	ldr	r2, =S3C2410_SRCPND
24	ldr	r3, =S3C2410_EINTPEND
25
26	teq	r0, r0
27	bl	s3c2412_sleep_enter1
28	teq	pc, r0
29	bl	s3c2412_sleep_enter1
30
31	.align	5
32
33	/* this is called twice, first with the Z flag to ensure that the
34	 * instructions have been loaded into the cache, and the second
35	 * time to try and suspend the system.
36	*/
37s3c2412_sleep_enter1:
38	mcr	p15, 0, r0, c7, c10, 4
39	mcrne	p15, 0, r0, c7, c0, 4
40
41	/* if we return from here, it is because an interrupt was
42	 * active when we tried to shutdown. Try and ack the IRQ and
43	 * retry, as simply returning causes the system to lock.
44	*/
45
46	ldrne	r9, [r1]
47	strne	r9, [r1]
48	ldrne	r9, [r2]
49	strne	r9, [r2]
50	ldrne	r9, [r3]
51	strne	r9, [r3]
52	bne	s3c2412_sleep_enter1
53
54	ret	lr
55